
#include "pub_var.h"
#include <QSize>
#include <QMessageBox>
#include <QDebug>
#include <QDate>
#include <QRegExp>
//#include <QTableWidget>
//#include <QTableWidgetItem>
#include <QTableView>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QEventLoop>
#include <QFile>
#include <QSqlError>
#include <QSqlRecord>

/* https://the-x.cn/cryptography/Sm4.aspx */
#include "sm4.h"

#include <windows.h>
#include <QLibrary>
#include <QCoreApplication>
#include <QAxObject>
#include <QDir>
#include <QElapsedTimer>
#include <QTemporaryFile>
#include <QProcess>
#include <QRegularExpression>

QSqlDatabase pub::db_m = QSqlDatabase::addDatabase("QMYSQL","pub::db_m");
QSqlDatabase pub::db_o = QSqlDatabase::addDatabase("QOCI","pub::db_o");
QSqlQuery pub::qr = QSqlQuery(pub::db_m);
//QSqlQuery pub::qrm = QSqlQuery(pub::db_m);
//QSqlQueryModel pub::md = QSqlQueryModel::setQuery(qr);

bool pub::DEBUG = true;  //调试标志
pub::pIT pub::BUSINESS = NULL;

pub::pInit pub::Init = NULL;
pub::pDailySinIn pub::DailySinIn = NULL;
pub::pEcQuery pub::EcQuery = NULL;
pub::pReadSFZ pub::ReadSFZ = NULL;
pub::pReadCardBas pub::ReadCardBas = NULL;
pub::pChangePIN pub::ChangePIN = NULL;

//bool pub::useInsurance = true;
bool pub::useInsurance = false;

QString pub::ybywzq = "";       //医保业务周期号
QString pub::ybywzqAtinc = "";  //交易atinc
QString pub::localIP = "";
QString pub::localMac = "";
QString pub::hos_name = "";    //医院名称
QString pub::hos_code = "";    //医院编码
QString pub::hos_ybbh_old = "";    //医院医保编号（旧）
QString pub::hos_ybbh = "";    //医院医保编号

QString pub::local_version = "";  //本地版本号

QString pub::medins_type = "D110"; //医疗服务机构类型
QString pub::medins_lv = "9";//医院等级

QString pub::usr_name = "";    //用户姓名
QString pub::usr_code = "";    //用户代码
QString pub::dp_name = "";    //科室名称
QString pub::dp_code = "";    //科室代码
QString pub::dp_name_st = "";    //科室名称
QString pub::dp_code_st = "";    //科室代码
QString pub::LOGINSESSION = ""; //登录session
//QString pub::hos_ybbh_new = "";    //贯标医保编号
QString pub::hos_ybjy = "";    //医保交易中台
QString pub::hos_dzpz = "";    //电子凭证中台
QString pub::hos_ybjy_ip = "";    //医保交易中台
QString pub::hos_ybjy_port = "";    //医保交易中台
QString pub::hos_ybjy_tail = "";    //医保交易中台

//QString pub::hos_ybjy_t = "";    //医保交易中台测试用
//QString pub::hos_ybjy_ip_t = "";    //医保交易中台测试用
//QString pub::hos_ybjy_port_t = "";    //医保交易中台测试用
//QString pub::hos_ybjy_tail_t = "";    //医保交易中台测试用
QString pub::zj_push_ip = "";  //诊间，推送ip
QString pub::app_id = "";
QString pub::key_sm4 = "";
QString pub::key_pub_app = "";
QString pub::key_private_app = "";
QString pub::key_pub_pub = "";

QString pub::hos_dzpz_ip = "";    //电子凭证中台
QString pub::hos_dzpz_port = "";    //电子凭证中台
QString pub::hos_dzpz_tail = "";    //电子凭证中台
QString pub::hos_insuplc = "";  //参保区划
QString pub::local_carddriver = "";  //本机读卡器型号
QString pub::hos_hiscode = ""; //  开发商代码
QString pub::hos_secretcode = ""; //  安全管理码


bool pub::userValidated = false;   //用户身份验证

QString pub::sign_no = ""; //医保登录ID
QString pub::sign_time = ""; //医保登录ID

QString pub::otp_mulaid_used_flag = "1"; //是否使用职工门诊共济
QString pub::downloadPath;//文件下载路径
QString pub::base_path;

QString pub::dr_codg = "";//医保编码
QString pub::dr_senior = "";//带教医师编码
QString pub::dr_profttl = ""; //	医师职称	 字典表
QString pub::dr_duty_range = ""; //	医师执业范围，中医，西医，中西医

QString pub::druged_oper_code;//处方药品调配
QString pub::send_oper_code;//处方药品发药

QElapsedTimer pub::elps;    //计时器

bool pub::cardFinish;
int pub::cardResult = -1;
QString pub::cardRet1 = ""; //
QString pub::cardRet2 = ""; //

QString pub::strChineseFirstPY =
        "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJGYZZJJFKCCLZDHWDWZJLJPFYYNWJJTMYHZWZHFLZPPQHGSCYYYNJQYXXGJ"
        "HHSDSJNKKTMOMLCRXYPSNQSECCQZGGLLYJLMYZZSECYKYYHQWJSSGGYXYZYJWWKDJHYCHMYXJTLXJYQBYXZLDWRDJRWYSRLDZJPC"
        "BZJJBRCFTLECZSTZFXXZHTRQHYBDLYCZSSYMMRFMYQZPWWJJYFCRWFDFZQPYDDWYXKYJAWJFFXYPSFTZYHHYZYSWCJYXSCLCXXWZ"
        "ZXNBGNNXBXLZSZSBSGPYSYZDHMDZBQBZCWDZZYYTZHBTSYYBZGNTNXQYWQSKBPHHLXGYBFMJEBJHHGQTJCYSXSTKZHLYCKGLYSMZ"
        "XYALMELDCCXGZYRJXSDLTYZCQKCNNJWHJTZZCQLJSTSTBNXBTYXCEQXGKWJYFLZQLYHYXSPSFXLMPBYSXXXYDJCZYLLLSJXFHJXP"
        "JBTFFYABYXBHZZBJYZLWLCZGGBTSSMDTJZXPTHYQTGLJSCQFZKJZJQNLZWLSLHDZBWJNCJZYZSQQYCQYRZCJJWYBRTWPYFTWEXCS"
        "KDZCTBZHYZZYYJXZCFFZZMJYXXSDZZOTTBZLQWFCKSZSXFYRLNYJMBDTHJXSQQCCSBXYYTSYFBXDZTGBCNSLCYZZPSAZYZZSCJCS"
        "HZQYDXLBPJLLMQXTYDZXSQJTZPXLCGLQTZWJBHCTSYJSFXYEJJTLBGXSXJMYJQQPFZASYJNTYDJXKJCDJSZCBARTDCLYJQMWNQNC"
        "LLLKBYBZZSYHQQLTWLCCXTXLLZNTYLNEWYZYXCZXXGRKRMTCNDNJTSYYSSDQDGHSDBJGHRWRQLYBGLXHLGTGXBQJDZPYJSJYJCTM"
        "RNYMGRZJCZGJMZMGXMPRYXKJNYMSGMZJYMKMFXMLDTGFBHCJHKYLPFMDXLQJJSMTQGZSJLQDLDGJYCALCMZCSDJLLNXDJFFFFJCZ"
        "FMZFFPFKHKGDPSXKTACJDHHZDDCRRCFQYJKQCCWJDXHWJLYLLZGCFCQDSMLZPBJJPLSBCJGGDCKKDEZSQCCKJGCGKDJTJDLZYCXK"
        "LQSCGJCLTFPCQCZGWPJDQYZJJBYJHSJDZWGFSJGZKQCCZLLPSPKJGQJHZZLJPLGJGJJTHJJYJZCZMLZLYQBGJWMLJKXZDZNJQSYZ"
        "MLJLLJKYWXMKJLHSKJGBMCLYYMKXJQLBMLLKMDXXKWYXYSLMLPSJQQJQXYXFJTJDXMXXLLCXQBSYJBGWYMBGGBCYXPJYGPEPFGDJ"
        "GBHBNSQJYZJKJKHXQFGQZKFHYGKHDKLLSDJQXPQYKYBNQSXQNSZSWHBSXWHXWBZZXDMNSJBSBKBBZKLYLXGWXDRWYQZMYWSJQLCJ"
        "XXJXKJEQXSCYETLZHLYYYSDZPAQYZCMTLSHTZCFYZYXYLJSDCJQAGYSLCQLYYYSHMRQQKLDXZSCSSSYDYCJYSFSJBFRSSZQSBXXP"
        "XJYSDRCKGJLGDKZJZBDKTCSYQPYHSTCLDJDHMXMCGXYZHJDDTMHLTXZXYLYMOHYJCLTYFBQQXPFBDFHHTKSQHZYYWCNXXCRWHOWG"
        "YJLEGWDQCWGFJYCSNTMYTOLBYGWQWESJPWNMLRYDZSZTXYQPZGCWXHNGPYXSHMYQJXZTDPPBFYHZHTJYFDZWKGKZBLDNTSXHQEEG"
        "ZZYLZMMZYJZGXZXKHKSTXNXXWYLYAPSTHXDWHZYMPXAGKYDXBHNHXKDPJNMYHYLPMGOCSLNZHKXXLPZZLBMLSFBHHGYGYYGGBHSC"
        "YAQTYWLXTZQCEZYDQDQMMHTKLLSZHLSJZWFYHQSWSCWLQAZYNYTLSXTHAZNKZZSZZLAXXZWWCTGQQTDDYZTCCHYQZFLXPSLZYGPZ"
        "SZNGLNDQTBDLXGTCTAJDKYWNSYZLJHHZZCWNYYZYWMHYCHHYXHJKZWSXHZYXLYSKQYSPSLYZWMYPPKBYGLKZHTYXAXQSYSHXASMC"
        "HKDSCRSWJPWXSGZJLWWSCHSJHSQNHCSEGNDAQTBAALZZMSSTDQJCJKTSCJAXPLGGXHHGXXZCXPDMMHLDGTYBYSJMXHMRCPXXJZCK"
        "ZXSHMLQXXTTHXWZFKHCCZDYTCJYXQHLXDHYPJQXYLSYYDZOZJNYXQEZYSQYAYXWYPDGXDDXSPPYZNDLTWRHXYDXZZJHTCXMCZLHP"
        "YYYYMHZLLHNXMYLLLMDCPPXHMXDKYCYRDLTXJCHHZZXZLCCLYLNZSHZJZZLNNRLWHYQSNJHXYNTTTKYJPYCHHYEGKCTTWLGQRLGG"
        "TGTYGYHPYHYLQYQGCWYQKPYYYTTTTLHYHLLTYTTSPLKYZXGZWGPYDSSZZDQXSKCQNMJJZZBXYQMJRTFFBTKHZKBXLJJKDXJTLBWF"
        "ZPPTKQTZTGPDGNTPJYFALQMKGXBDCLZFHZCLLLLADPMXDJHLCCLGYHDZFGYDDGCYYFGYDXKSSEBDHYKDKDKHNAXXYBPBYYHXZQGA"
        "FFQYJXDMLJCSQZLLPCHBSXGJYNDYBYQSPZWJLZKSDDTACTBXZDYZYPJZQSJNKKTKNJDJGYYPGTLFYQKASDNTCYHBLWDZHBBYDWJR"
        "YGKZYHEYYFJMSDTYFZJJHGCXPLXHLDWXXJKYTCYKSSSMTWCTTQZLPBSZDZWZXGZAGYKTYWXLHLSPBCLLOQMMZSSLCMBJCSZZKYDC"
        "ZJGQQDSMCYTZQQLWZQZXSSFPTTFQMDDZDSHDTDWFHTDYZJYQJQKYPBDJYYXTLJHDRQXXXHAYDHRJLKLYTWHLLRLLRCXYLBWSRSZZ"
        "SYMKZZHHKYHXKSMDSYDYCJPBZBSQLFCXXXNXKXWYWSDZYQOGGQMMYHCDZTTFJYYBGSTTTYBYKJDHKYXBELHTYPJQNFXFDYKZHQKZ"
        "BYJTZBXHFDXKDASWTAWAJLDYJSFHBLDNNTNQJTJNCHXFJSRFWHZFMDRYJYJWZPDJKZYJYMPCYZNYNXFBYTFYFWYGDBNZZZDNYTXZ"
        "EMMQBSQEHXFZMBMFLZZSRXYMJGSXWZJSPRYDJSJGXHJJGLJJYNZZJXHGXKYMLPYYYCXYTWQZSWHWLYRJLPXSLSXMFSWWKLCTNXNY"
        "NPSJSZHDZEPTXMYYWXYYSYWLXJQZQXZDCLEEELMCPJPCLWBXSQHFWWTFFJTNQJHJQDXHWLBYZNFJLALKYYJLDXHHYCSTYYWNRJYX"
        "YWTRMDRQHWQCMFJDYZMHMYYXJWMYZQZXTLMRSPWWCHAQBXYGZYPXYYRRCLMPYMGKSJSZYSRMYJSNXTPLNBAPPYPYLXYYZKYNLDZY"
        "JZCZNNLMZHHARQMPGWQTZMXXMLLHGDZXYHXKYXYCJMFFYYHJFSBSSQLXXNDYCANNMTCJCYPRRNYTYQNYYMBMSXNDLYLYSLJRLXYS"
        "XQMLLYZLZJJJKYZZCSFBZXXMSTBJGNXYZHLXNMCWSCYZYFZLXBRNNNYLBNRTGZQYSATSWRYHYJZMZDHZGZDWYBSSCSKXSYHYTXXG"
        "CQGXZZSHYXJSCRHMKKBXCZJYJYMKQHZJFNBHMQHYSNJNZYBKNQMCLGQHWLZNZSWXKHLJHYYBQLBFCDSXDLDSPFZPSKJYZWZXZDDX"
        "JSMMEGJSCSSMGCLXXKYYYLNYPWWWGYDKZJGGGZGGSYCKNJWNJPCXBJJTQTJWDSSPJXZXNZXUMELPXFSXTLLXCLJXJJLJZXCTPSWX"
        "LYDHLYQRWHSYCSQYYBYAYWJJJQFWQCQQCJQGXALDBZZYJGKGXPLTZYFXJLTPADKYQHPMATLCPDCKBMTXYBHKLENXDLEEGQDYMSAW"
        "HZMLJTWYGXLYQZLJEEYYBQQFFNLYXRDSCTGJGXYYNKLLYQKCCTLHJLQMKKZGCYYGLLLJDZGYDHZWXPYSJBZKDZGYZZHYWYFQYTYZ"
        "SZYEZZLYMHJJHTSMQWYZLKYYWZCSRKQYTLTDXWCTYJKLWSQZWBDCQYNCJSRSZJLKCDCDTLZZZACQQZZDDXYPLXZBQJYLZLLLQDDZ"
        "QJYJYJZYXNYYYNYJXKXDAZWYRDLJYYYRJLXLLDYXJCYWYWNQCCLDDNYYYNYCKCZHXXCCLGZQJGKWPPCQQJYSBZZXYJSQPXJPZBSB"
        "DSFNSFPZXHDWZTDWPPTFLZZBZDMYYPQJRSDZSQZSQXBDGCPZSWDWCSQZGMDHZXMWWFYBPDGPHTMJTHZSMMBGZMBZJCFZWFZBBZMQ"
        "CFMBDMCJXLGPNJBBXGYHYYJGPTZGZMQBQTCGYXJXLWZKYDPDYMGCFTPFXYZTZXDZXTGKMTYBBCLBJASKYTSSQYYMSZXFJEWLXLLS"
        "ZBQJJJAKLYLXLYCCTSXMCWFKKKBSXLLLLJYXTYLTJYYTDPJHNHNNKBYQNFQYYZBYYESSESSGDYHFHWTCJBSDZZTFDMXHCNJZYMQW"
        "SRYJDZJQPDQBBSTJGGFBKJBXTGQHNGWJXJGDLLTHZHHYYYYYYSXWTYYYCCBDBPYPZYCCZYJPZYWCBDLFWZCWJDXXHYHLHWZZXJTC"
        "ZLCDPXUJCZZZLYXJJTXPHFXWPYWXZPTDZZBDZCYHJHMLXBQXSBYLRDTGJRRCTTTHYTCZWMXFYTWWZCWJWXJYWCSKYBZSCCTZQNHX"
        "NWXXKHKFHTSWOCCJYBCMPZZYKBNNZPBZHHZDLSYDDYTYFJPXYNGFXBYQXCBHXCPSXTYZDMKYSNXSXLHKMZXLYHDHKWHXXSSKQYHH"
        "CJYXGLHZXCSNHEKDTGZXQYPKDHEXTYKCNYMYYYPKQYYYKXZLTHJQTBYQHXBMYHSQCKWWYLLHCYYLNNEQXQWMCFBDCCMLJGGXDQKT"
        "LXKGNQCDGZJWYJJLYHHQTTTNWCHMXCXWHWSZJYDJCCDBQCDGDNYXZTHCQRXCBHZTQCBXWGQWYYBXHMBYMYQTYEXMQKYAQYRGYZSL"
        "FYKKQHYSSQYSHJGJCNXKZYCXSBXYXHYYLSTYCXQTHYSMGSCPMMGCCCCCMTZTASMGQZJHKLOSQYLSWTMXSYQKDZLJQQYPLSYCZTCQ"
        "QPBBQJZCLPKHQZYYXXDTDDTSJCXFFLLCHQXMJLWCJCXTSPYCXNDTJSHJWXDQQJSKXYAMYLSJHMLALYKXCYYDMNMDQMXMCZNNCYBZ"
        "KKYFLMCHCMLHXRCJJHSYLNMTJZGZGYWJXSRXCWJGJQHQZDQJDCJJZKJKGDZQGJJYJYLXZXXCDQHHHEYTMHLFSBDJSYYSHFYSTCZQ"
        "LPBDRFRZTZYKYWHSZYQKWDQZRKMSYNBCRXQBJYFAZPZZEDZCJYWBCJWHYJBQSZYWRYSZPTDKZPFPBNZTKLQYHBBZPNPPTYZZYBQN"
        "YDCPJMMCYCQMCYFZZDCMNLFPBPLNGQJTBTTNJZPZBBZNJKLJQYLNBZQHKSJZNGGQSZZKYXSHPZSNBCGZKDDZQANZHJKDRTLZLSWJ"
        "LJZLYWTJNDJZJHXYAYNCBGTZCSSQMNJPJYTYSWXZFKWJQTKHTZPLBHSNJZSYZBWZZZZLSYLSBJHDWWQPSLMMFBJDWAQYZTCJTBNN"
        "WZXQXCDSLQGDSDPDZHJTQQPSWLYYJZLGYXYZLCTCBJTKTYCZJTQKBSJLGMGZDMCSGPYNJZYQYYKNXRPWSZXMTNCSZZYXYBYHYZAX"
        "YWQCJTLLCKJJTJHGDXDXYQYZZBYWDLWQCGLZGJGQRQZCZSSBCRPCSKYDZNXJSQGXSSJMYDNSTZTPBDLTKZWXQWQTZEXNQCZGWEZK"
        "SSBYBRTSSSLCCGBPSZQSZLCCGLLLZXHZQTHCZMQGYZQZNMCOCSZJMMZSQPJYGQLJYJPPLDXRGZYXCCSXHSHGTZNLZWZKJCXTCFCJ"
        "XLBMQBCZZWPQDNHXLJCTHYZLGYLNLSZZPCXDSCQQHJQKSXZPBAJYEMSMJTZDXLCJYRYYNWJBNGZZTMJXLTBSLYRZPYLSSCNXPHLL"
        "HYLLQQZQLXYMRSYCXZLMMCZLTZSDWTJJLLNZGGQXPFSKYGYGHBFZPDKMWGHCXMSGDXJMCJZDYCABXJDLNBCDQYGSKYDQTXDJJYXM"
        "SZQAZDZFSLQXYJSJZYLBTXXWXQQZBJZUFBBLYLWDSLJHXJYZJWTDJCZFQZQZZDZSXZZQLZCDZFJHYSPYMPQZMLPPLFFXJJNZZYLS"
        "JEYQZFPFZKSYWJJJHRDJZZXTXXGLGHYDXCSKYSWMMZCWYBAZBJKSHFHJCXMHFQHYXXYZFTSJYZFXYXPZLCHMZMBXHZZSXYFYMNCW"
        "DABAZLXKTCSHHXKXJJZJSTHYGXSXYYHHHJWXKZXSSBZZWHHHCWTZZZPJXSNXQQJGZYZYWLLCWXZFXXYXYHXMKYYSWSQMNLNAYCYS"
        "PMJKHWCQHYLAJJMZXHMMCNZHBHXCLXTJPLTXYJHDYYLTTXFSZHYXXSJBJYAYRSMXYPLCKDUYHLXRLNLLSTYZYYQYGYHHSCCSMZCT"
        "ZQXKYQFPYYRPFFLKQUNTSZLLZMWWTCQQYZWTLLMLMPWMBZSSTZRBPDDTLQJJBXZCSRZQQYGWCSXFWZLXCCRSZDZMCYGGDZQSGTJS"
        "WLJMYMMZYHFBJDGYXCCPSHXNZCSBSJYJGJMPPWAFFYFNXHYZXZYLREMZGZCYZSSZDLLJCSQFNXZKPTXZGXJJGFMYYYSNBTYLBNLH"
        "PFZDCYFBMGQRRSSSZXYSGTZRNYDZZCDGPJAFJFZKNZBLCZSZPSGCYCJSZLMLRSZBZZLDLSLLYSXSQZQLYXZLSKKBRXBRBZCYCXZZ"
        "ZEEYFGKLZLYYHGZSGZLFJHGTGWKRAAJYZKZQTSSHJJXDCYZUYJLZYRZDQQHGJZXSSZBYKJPBFRTJXLLFQWJHYLQTYMBLPZDXTZYG"
        "BDHZZRBGXHWNJTJXLKSCFSMWLSDQYSJTXKZSCFWJLBXFTZLLJZLLQBLSQMQQCGCZFPBPHZCZJLPYYGGDTGWDCFCZQYYYQYSSCLXZ"
        "SKLZZZGFFCQNWGLHQYZJJCZLQZZYJPJZZBPDCCMHJGXDQDGDLZQMFGPSYTSDYFWWDJZJYSXYYCZCYHZWPBYKXRYLYBHKJKSFXTZJ"
        "MMCKHLLTNYYMSYXYZPYJQYCSYCWMTJJKQYRHLLQXPSGTLYYCLJSCPXJYZFNMLRGJJTYZBXYZMSJYJHHFZQMSYXRSZCWTLRTQZSST"
        "KXGQKGSPTGCZNJSJCQCXHMXGGZTQYDJKZDLBZSXJLHYQGGGTHQSZPYHJHHGYYGKGGCWJZZYLCZLXQSFTGZSLLLMLJSKCTBLLZZSZ"
        "MMNYTPZSXQHJCJYQXYZXZQZCPSHKZZYSXCDFGMWQRLLQXRFZTLYSTCTMJCXJJXHJNXTNRZTZFQYHQGLLGCXSZSJDJLJCYDSJTLNY"
        "XHSZXCGJZYQPYLFHDJSBPCCZHJJJQZJQDYBSSLLCMYTTMQTBHJQNNYGKYRQYQMZGCJKPDCGMYZHQLLSLLCLMHOLZGDYYFZSLJCQZ"
        "LYLZQJESHNYLLJXGJXLYSYYYXNBZLJSSZCQQCJYLLZLTJYLLZLLBNYLGQCHXYYXOXCXQKYJXXXYKLXSXXYQXCYKQXQCSGYXXYQXY"
        "GYTQOHXHXPYXXXULCYEYCHZZCBWQBBWJQZSCSZSSLZYLKDESJZWMYMCYTSDSXXSCJPQQSQYLYYZYCMDJDZYWCBTJSYDJKCYDDJLB"
        "DJJSODZYSYXQQYXDHHGQQYQHDYXWGMMMAJDYBBBPPBCMUUPLJZSMTXERXJMHQNUTPJDCBSSMSSSTKJTSSMMTRCPLZSZMLQDSDMJM"
        "QPNQDXCFYNBFSDQXYXHYAYKQYDDLQYYYSSZBYDSLNTFQTZQPZMCHDHCZCWFDXTMYQSPHQYYXSRGJCWTJTZZQMGWJJTJHTQJBBHWZ"
        "PXXHYQFXXQYWYYHYSCDYDHHQMNMTMWCPBSZPPZZGLMZFOLLCFWHMMSJZTTDHZZYFFYTZZGZYSKYJXQYJZQBHMBZZLYGHGFMSHPZF"
        "ZSNCLPBQSNJXZSLXXFPMTYJYGBXLLDLXPZJYZJYHHZCYWHJYLSJEXFSZZYWXKZJLUYDTMLYMQJPWXYHXSKTQJEZRPXXZHHMHWQPW"
        "QLYJJQJJZSZCPHJLCHHNXJLQWZJHBMZYXBDHHYPZLHLHLGFWLCHYYTLHJXCJMSCPXSTKPNHQXSRTYXXTESYJCTLSSLSTDLLLWWYH"
        "DHRJZSFGXTSYCZYNYHTDHWJSLHTZDQDJZXXQHGYLTZPHCSQFCLNJTCLZPFSTPDYNYLGMJLLYCQHYSSHCHYLHQYQTMZYPBYWRFQYK"
        "QSYSLZDQJMPXYYSSRHZJNYWTQDFZBWWTWWRXCWHGYHXMKMYYYQMSMZHNGCEPMLQQMTCWCTMMPXJPJJHFXYYZSXZHTYBMSTSYJTTQ"
        "QQYYLHYNPYQZLCYZHZWSMYLKFJXLWGXYPJYTYSYXYMZCKTTWLKSMZSYLMPWLZWXWQZSSAQSYXYRHSSNTSRAPXCPWCMGDXHXZDZYF"
        "JHGZTTSBJHGYZSZYSMYCLLLXBTYXHBBZJKSSDMALXHYCFYGMQYPJYCQXJLLLJGSLZGQLYCJCCZOTYXMTMTTLLWTGPXYMZMKLPSZZ"
        "ZXHKQYSXCTYJZYHXSHYXZKXLZWPSQPYHJWPJPWXQQYLXSDHMRSLZZYZWTTCYXYSZZSHBSCCSTPLWSSCJCHNLCGCHSSPHYLHFHHXJ"
        "SXYLLNYLSZDHZXYLSXLWZYKCLDYAXZCMDDYSPJTQJZLNWQPSSSWCTSTSZLBLNXSMNYYMJQBQHRZWTYYDCHQLXKPZWBGQYBKFCMZW"
        "PZLLYYLSZYDWHXPSBCMLJBSCGBHXLQHYRLJXYSWXWXZSLDFHLSLYNJLZYFLYJYCDRJLFSYZFSLLCQYQFGJYHYXZLYLMSTDJCYHBZ"
        "LLNWLXXYGYYHSMGDHXXHHLZZJZXCZZZCYQZFNGWPYLCPKPYYPMCLQKDGXZGGWQBDXZZKZFBXXLZXJTPJPTTBYTSZZDWSLCHZHSLT"
        "YXHQLHYXXXYYZYSWTXZKHLXZXZPYHGCHKCFSYHUTJRLXFJXPTZTWHPLYXFCRHXSHXKYXXYHZQDXQWULHYHMJTBFLKHTXCWHJFWJC"
        "FPQRYQXCYYYQYGRPYWSGSUNGWCHKZDXYFLXXHJJBYZWTSXXNCYJJYMSWZJQRMHXZWFQSYLZJZGBHYNSLBGTTCSYBYXXWXYHXYYXN"
        "SQYXMQYWRGYQLXBBZLJSYLPSYTJZYHYZAWLRORJMKSCZJXXXYXCHDYXRYXXJDTSQFXLYLTSFFYXLMTYJMJUYYYXLTZCSXQZQHZXL"
        "YYXZHDNBRXXXJCTYHLBRLMBRLLAXKYLLLJLYXXLYCRYLCJTGJCMTLZLLCYZZPZPCYAWHJJFYBDYYZSMPCKZDQYQPBPCJPDCYZMDP"
        "BCYYDYCNNPLMTMLRMFMMGWYZBSJGYGSMZQQQZTXMKQWGXLLPJGZBQCDJJJFPKJKCXBLJMSWMDTQJXLDLPPBXCWRCQFBFQJCZAHZG"
        "MYKPHYYHZYKNDKZMBPJYXPXYHLFPNYYGXJDBKXNXHJMZJXSTRSTLDXSKZYSYBZXJLXYSLBZYSLHXJPFXPQNBYLLJQKYGZMCYZZYM"
        "CCSLCLHZFWFWYXZMWSXTYNXJHPYYMCYSPMHYSMYDYSHQYZCHMJJMZCAAGCFJBBHPLYZYLXXSDJGXDHKXXTXXNBHRMLYJSLTXMRHN"
        "LXQJXYZLLYSWQGDLBJHDCGJYQYCMHWFMJYBMBYJYJWYMDPWHXQLDYGPDFXXBCGJSPCKRSSYZJMSLBZZJFLJJJLGXZGYXYXLSZQYX"
        "BEXYXHGCXBPLDYHWETTWWCJMBTXCHXYQXLLXFLYXLLJLSSFWDPZSMYJCLMWYTCZPCHQEKCQBWLCQYDPLQPPQZQFJQDJHYMMCXTXD"
        "RMJWRHXCJZYLQXDYYNHYYHRSLSRSYWWZJYMTLTLLGTQCJZYABTCKZCJYCCQLJZQXALMZYHYWLWDXZXQDLLQSHGPJFJLJHJABCQZD"
        "JGTKHSSTCYJLPSWZLXZXRWGLDLZRLZXTGSLLLLZLYXXWGDZYGBDPHZPBRLWSXQBPFDWOFMWHLYPCBJCCLDMBZPBZZLCYQXLDOMZB"
        "LZWPDWYYGDSTTHCSQSCCRSSSYSLFYBFNTYJSZDFNDPDHDZZMBBLSLCMYFFGTJJQWFTMTPJWFNLBZCMMJTGBDZLQLPYFHYYMJYLSD"
        "CHDZJWJCCTLJCLDTLJJCPDDSQDSSZYBNDBJLGGJZXSXNLYCYBJXQYCBYLZCFZPPGKCXZDZFZTJJFJSJXZBNZYJQTTYJYHTYCZHYM"
        "DJXTTMPXSPLZCDWSLSHXYPZGTFMLCJTYCBPMGDKWYCYZCDSZZYHFLYCTYGWHKJYYLSJCXGYWJCBLLCSNDDBTZBSCLYZCZZSSQDLL"
        "MQYYHFSLQLLXFTYHABXGWNYWYYPLLSDLDLLBJCYXJZMLHLJDXYYQYTDLLLBUGBFDFBBQJZZMDPJHGCLGMJJPGAEHHBWCQXAXHHHZ"
        "CHXYPHJAXHLPHJPGPZJQCQZGJJZZUZDMQYYBZZPHYHYBWHAZYJHYKFGDPFQSDLZMLJXKXGALXZDAGLMDGXMWZQYXXDXXPFDMMSSY"
        "MPFMDMMKXKSYZYSHDZKXSYSMMZZZMSYDNZZCZXFPLSTMZDNMXCKJMZTYYMZMZZMSXHHDCZJEMXXKLJSTLWLSQLYJZLLZJSSDPPMH"
        "NLZJCZYHMXXHGZCJMDHXTKGRMXFWMCGMWKDTKSXQMMMFZZYDKMSCLCMPCGMHSPXQPZDSSLCXKYXTWLWJYAHZJGZQMCSNXYYMMPML"
        "KJXMHLMLQMXCTKZMJQYSZJSYSZHSYJZJCDAJZYBSDQJZGWZQQXFKDMSDJLFWEHKZQKJPEYPZYSZCDWYJFFMZZYLTTDZZEFMZLBNP"
        "PLPLPEPSZALLTYLKCKQZKGENQLWAGYXYDPXLHSXQQWQCQXQCLHYXXMLYCCWLYMQYSKGCHLCJNSZKPYZKCQZQLJPDMDZHLASXLBYD"
        "WQLWDNBQCRYDDZTJYBKBWSZDXDTNPJDTCTQDFXQQMGNXECLTTBKPWSLCTYQLPWYZZKLPYGZCQQPLLKCCYLPQMZCZQCLJSLQZDJXL"
        "DDHPZQDLJJXZQDXYZQKZLJCYQDYJPPYPQYKJYRMPCBYMCXKLLZLLFQPYLLLMBSGLCYSSLRSYSQTMXYXZQZFDZUYSYZTFFMZZSMZQ"
        "HZSSCCMLYXWTPZGXZJGZGSJSGKDDHTQGGZLLBJDZLCBCHYXYZHZFYWXYZYMSDBZZYJGTSMTFXQYXQSTDGSLNXDLRYZZLRYYLXQHT"
        "XSRTZNGZXBNQQZFMYKMZJBZYMKBPNLYZPBLMCNQYZZZSJZHJCTZKHYZZJRDYZHNPXGLFZTLKGJTCTSSYLLGZRZBBQZZKLPKLCZYS"
        "SUYXBJFPNJZZXCDWXZYJXZZDJJKGGRSRJKMSMZJLSJYWQSKYHQJSXPJZZZLSNSHRNYPZTWCHKLPSRZLZXYJQXQKYSJYCZTLQZYBB"
        "YBWZPQDWWYZCYTJCJXCKCWDKKZXSGKDZXWWYYJQYYTCYTDLLXWKCZKKLCCLZCQQDZLQLCSFQCHQHSFSMQZZLNBJJZBSJHTSZDYSJ"
        "QJPDLZCDCWJKJZZLPYCGMZWDJJBSJQZSYZYHHXJPBJYDSSXDZNCGLQMBTSFSBPDZDLZNFGFJGFSMPXJQLMBLGQCYYXBQKDJJQYRF"
        "KZTJDHCZKLBSDZCFJTPLLJGXHYXZCSSZZXSTJYGKGCKGYOQXJPLZPBPGTGYJZGHZQZZLBJLSQFZGKQQJZGYCZBZQTLDXRJXBSXXP"
        "ZXHYZYCLWDXJJHXMFDZPFZHQHQMQGKSLYHTYCGFRZGNQXCLPDLBZCSCZQLLJBLHBZCYPZZPPDYMZZSGYHCKCPZJGSLJLNSCDSLDL"
        "XBMSTLDDFJMKDJDHZLZXLSZQPQPGJLLYBDSZGQLBZLSLKYYHZTTNTJYQTZZPSZQZTLLJTYYLLQLLQYZQLBDZLSLYYZYMDFSZSNHL"
        "XZNCZQZPBWSKRFBSYZMTHBLGJPMCZZLSTLXSHTCSYZLZBLFEQHLXFLCJLYLJQCBZLZJHHSSTBRMHXZHJZCLXFNBGXGTQJCZTMSFZ"
        "KJMSSNXLJKBHSJXNTNLZDNTLMSJXGZJYJCZXYJYJWRWWQNZTNFJSZPZSHZJFYRDJSFSZJZBJFZQZZHZLXFYSBZQLZSGYFTZDCSZX"
        "ZJBQMSZKJRHYJZCKMJKHCHGTXKXQGLXPXFXTRTYLXJXHDTSJXHJZJXZWZLCQSBTXWXGXTXXHXFTSDKFJHZYJFJXRZSDLLLTQSQQZ"
        "QWZXSYQTWGWBZCGZLLYZBCLMQQTZHZXZXLJFRMYZFLXYSQXXJKXRMQDZDMMYYBSQBHGZMWFWXGMXLZPYYTGZYCCDXYZXYWGSYJYZ"
        "NBHPZJSQSYXSXRTFYZGRHZTXSZZTHCBFCLSYXZLZQMZLMPLMXZJXSFLBYZMYQHXJSXRXSQZZZSSLYFRCZJRCRXHHZXQYDYHXSJJH"
        "ZCXZBTYNSYSXJBQLPXZQPYMLXZKYXLXCJLCYSXXZZLXDLLLJJYHZXGYJWKJRWYHCPSGNRZLFZWFZZNSXGXFLZSXZZZBFCSYJDBRJ"
        "KRDHHGXJLJJTGXJXXSTJTJXLYXQFCSGSWMSBCTLQZZWLZZKXJMLTMJYHSDDBXGZHDLBMYJFRZFSGCLYJBPMLYSMSXLSZJQQHJZFX"
        "GFQFQBPXZGYYQXGZTCQWYLTLGWSGWHRLFSFGZJMGMGBGTJFSYZZGZYZAFLSSPMLPFLCWBJZCLJJMZLPJJLYMQDMYYYFBGYGYZMLY"
        "ZDXQYXRQQQHSYYYQXYLJTYXFSFSLLGNQCYHYCWFHCCCFXPYLYPLLZYXXXXXKQHHXSHJZCFZSCZJXCPZWHHHHHAPYLQALPQAFYHXD"
        "YLUKMZQGGGDDESRNNZLTZGCHYPPYSQJJHCLLJTOLNJPZLJLHYMHEYDYDSQYCDDHGZUNDZCLZYZLLZNTNYZGSLHSLPJJBDGWXPCDU"
        "TJCKLKCLWKLLCASSTKZZDNQNTTLYYZSSYSSZZRYLJQKCQDHHCRXRZYDGRGCWCGZQFFFPPJFZYNAKRGYWYQPQXXFKJTSZZXSWZDDF"
        "BBXTBGTZKZNPZZPZXZPJSZBMQHKCYXYLDKLJNYPKYGHGDZJXXEAHPNZKZTZCMXCXMMJXNKSZQNMNLWBWWXJKYHCPSTMCSQTZJYXT"
        "PCTPDTNNPGLLLZSJLSPBLPLQHDTNJNLYYRSZFFJFQWDPHZDWMRZCCLODAXNSSNYZRESTYJWJYJDBCFXNMWTTBYLWSTSZGYBLJPXG"
        "LBOCLHPCBJLTMXZLJYLZXCLTPNCLCKXTPZJSWCYXSFYSZDKNTLBYJCYJLLSTGQCBXRYZXBXKLYLHZLQZLNZCXWJZLJZJNCJHXMNZ"
        "ZGJZZXTZJXYCYYCXXJYYXJJXSSSJSTSSTTPPGQTCSXWZDCSYFPTFBFHFBBLZJCLZZDBXGCXLQPXKFZFLSYLTUWBMQJHSZBMDDBCY"
        "SCCLDXYCDDQLYJJWMQLLCSGLJJSYFPYYCCYLTJANTJJPWYCMMGQYYSXDXQMZHSZXPFTWWZQSWQRFKJLZJQQYFBRXJHHFWJJZYQAZ"
        "MYFRHCYYBYQWLPEXCCZSTYRLTTDMQLYKMBBGMYYJPRKZNPBSXYXBHYZDJDNGHPMFSGMWFZMFQMMBCMZZCJJLCNUXYQLMLRYGQZCY"
        "XZLWJGCJCGGMCJNFYZZJHYCPRRCMTZQZXHFQGTJXCCJEAQCRJYHPLQLSZDJRBCQHQDYRHYLYXJSYMHZYDWLDFRYHBPYDTSSCNWBX"
        "GLPZMLZZTQSSCPJMXXYCSJYTYCGHYCJWYRXXLFEMWJNMKLLSWTXHYYYNCMMCWJDQDJZGLLJWJRKHPZGGFLCCSCZMCBLTBHBQJXQD"
        "SPDJZZGKGLFQYWBZYZJLTSTDHQHCTCBCHFLQMPWDSHYYTQWCNZZJTLBYMBPDYYYXSQKXWYYFLXXNCWCXYPMAELYKKJMZZZBRXYYQ"
        "JFLJPFHHHYTZZXSGQQMHSPGDZQWBWPJHZJDYSCQWZKTXXSQLZYYMYSDZGRXCKKUJLWPYSYSCSYZLRMLQSYLJXBCXTLWDQZPCYCYK"
        "PPPNSXFYZJJRCEMHSZMSXLXGLRWGCSTLRSXBZGBZGZTCPLUJLSLYLYMTXMTZPALZXPXJTJWTCYYZLBLXBZLQMYLXPGHDSLSSDMXM"
        "BDZZSXWHAMLCZCPJMCNHJYSNSYGCHSKQMZZQDLLKABLWJXSFMOCDXJRRLYQZKJMYBYQLYHETFJZFRFKSRYXFJTWDSXXSYSQJYSLY"
        "XWJHSNLXYYXHBHAWHHJZXWMYLJCSSLKYDZTXBZSYFDXGXZJKHSXXYBSSXDPYNZWRPTQZCZENYGCXQFJYKJBZMLJCMQQXUOXSLYXX"
        "LYLLJDZBTYMHPFSTTQQWLHOKYBLZZALZXQLHZWRRQHLSTMYPYXJJXMQSJFNBXYXYJXXYQYLTHYLQYFMLKLJTMLLHSZWKZHLJMLHL"
        "JKLJSTLQXYLMBHHLNLZXQJHXCFXXLHYHJJGBYZZKBXSCQDJQDSUJZYYHZHHMGSXCSYMXFEBCQWWRBPYYJQTYZCYQYQQZYHMWFFHG"
        "ZFRJFCDPXNTQYZPDYKHJLFRZXPPXZDBBGZQSTLGDGYLCQMLCHHMFYWLZYXKJLYPQHSYWMQQGQZMLZJNSQXJQSYJYCBEHSXFSZPXZ"
        "WFLLBCYYJDYTDTHWZSFJMQQYJLMQXXLLDTTKHHYBFPWTYYSQQWNQWLGWDEBZWCMYGCULKJXTMXMYJSXHYBRWFYMWFRXYQMXYSZTZ"
        "ZTFYKMLDHQDXWYYNLCRYJBLPSXCXYWLSPRRJWXHQYPHTYDNXHHMMYWYTZCSQMTSSCCDALWZTCPQPYJLLQZYJSWXMZZMMYLMXCLMX"
        "CZMXMZSQTZPPQQBLPGXQZHFLJJHYTJSRXWZXSCCDLXTYJDCQJXSLQYCLZXLZZXMXQRJMHRHZJBHMFLJLMLCLQNLDXZLLLPYPSYJY"
        "SXCQQDCMQJZZXHNPNXZMEKMXHYKYQLXSXTXJYYHWDCWDZHQYYBGYBCYSCFGPSJNZDYZZJZXRZRQJJYMCANYRJTLDPPYZBSTJKXXZ"
        "YPFDWFGZZRPYMTNGXZQBYXNBUFNQKRJQZMJEGRZGYCLKXZDSKKNSXKCLJSPJYYZLQQJYBZSSQLLLKJXTBKTYLCCDDBLSPPFYLGYD"
        "TZJYQGGKQTTFZXBDKTYYHYBBFYTYYBCLPDYTGDHRYRNJSPTCSNYJQHKLLLZSLYDXXWBCJQSPXBPJZJCJDZFFXXBRMLAZHCSNDLBJ"
        "DSZBLPRZTSWSBXBCLLXXLZDJZSJPYLYXXYFTFFFBHJJXGBYXJPMMMPSSJZJMTLYZJXSWXTYLEDQPJMYGQZJGDJLQJWJQLLSJGJGY"
        "GMSCLJJXDTYGJQJQJCJZCJGDZZSXQGSJGGCXHQXSNQLZZBXHSGZXCXYLJXYXYYDFQQJHJFXDHCTXJYRXYSQTJXYEFYYSSYYJXNCY"
        "ZXFXMSYSZXYYSCHSHXZZZGZZZGFJDLTYLNPZGYJYZYYQZPBXQBDZTZCZYXXYHHSQXSHDHGQHJHGYWSZTMZMLHYXGEBTYLZKQWYTJ"
        "ZRCLEKYSTDBCYKQQSAYXCJXWWGSBHJYZYDHCSJKQCXSWXFLTYNYZPZCCZJQTZWJQDZZZQZLJJXLSBHPYXXPSXSHHEZTXFPTLQYZZ"
        "XHYTXNCFZYYHXGNXMYWXTZSJPTHHGYMXMXQZXTSBCZYJYXXTYYZYPCQLMMSZMJZZLLZXGXZAAJZYXJMZXWDXZSXZDZXLEYJJZQBH"
        "ZWZZZQTZPSXZTDSXJJJZNYAZPHXYYSRNQDTHZHYYKYJHDZXZLSWCLYBZYECWCYCRYLCXNHZYDZYDYJDFRJJHTRSQTXYXJRJHOJYN"
        "XELXSFSFJZGHPZSXZSZDZCQZBYYKLSGSJHCZSHDGQGXYZGXCHXZJWYQWGYHKSSEQZZNDZFKWYSSTCLZSTSYMCDHJXXYWEYXCZAYD"
        "MPXMDSXYBSQMJMZJMTZQLPJYQZCGQHXJHHLXXHLHDLDJQCLDWBSXFZZYYSCHTYTYYBHECXHYKGJPXHHYZJFXHWHBDZFYZBCAPNPG"
        "NYDMSXHMMMMAMYNBYJTMPXYYMCTHJBZYFCGTYHWPHFTWZZEZSBZEGPFMTSKFTYCMHFLLHGPZJXZJGZJYXZSBBQSCZZLZCCSTPGXM"
        "JSFTCCZJZDJXCYBZLFCJSYZFGSZLYBCWZZBYZDZYPSWYJZXZBDSYUXLZZBZFYGCZXBZHZFTPBGZGEJBSTGKDMFHYZZJHZLLZZGJQ"
        "ZLSFDJSSCBZGPDLFZFZSZYZYZSYGCXSNXXCHCZXTZZLJFZGQSQYXZJQDCCZTQCDXZJYQJQCHXZTDLGSCXZSYQJQTZWLQDQZTQCHQ"
        "QJZYEZZZPBWKDJFCJPZTYPQYQTTYNLMBDKTJZPQZQZZFPZSBNJLGYJDXJDZZKZGQKXDLPZJTCJDQBXDJQJSTCKNXBXZMSLYJCQMT"
        "JQWWCJQNJNLLLHJCWQTBZQYDZCZPZZDZYDDCYZZZCCJTTJFZDPRRTZTJDCQTQZDTJNPLZBCLLCTZSXKJZQZPZLBZRBTJDCXFCZDB"
        "CCJJLTQQPLDCGZDBBZJCQDCJWYNLLZYZCCDWLLXWZLXRXNTQQCZXKQLSGDFQTDDGLRLAJJTKUYMKQLLTZYTDYYCZGJWYXDXFRSKS"
        "TQTENQMRKQZHHQKDLDAZFKYPBGGPZREBZZYKZZSPEGJXGYKQZZZSLYSYYYZWFQZYLZZLZHWCHKYPQGNPGBLPLRRJYXCCSYYHSFZF"
        "YBZYYTGZXYLXCZWXXZJZBLFFLGSKHYJZEYJHLPLLLLCZGXDRZELRHGKLZZYHZLYQSZZJZQLJZFLNBHGWLCZCFJYSPYXZLZLXGCCP"
        "ZBLLCYBBBBUBBCBPCRNNZCZYRBFSRLDCGQYYQXYGMQZWTZYTYJXYFWTEHZZJYWLCCNTZYJJZDEDPZDZTSYQJHDYMBJNYJZLXTSST"
        "PHNDJXXBYXQTZQDDTJTDYYTGWSCSZQFLSHLGLBCZPHDLYZJYCKWTYTYLBNYTSDSYCCTYSZYYEBHEXHQDTWNYGYCLXTSZYSTQMYGZ"
        "AZCCSZZDSLZCLZRQXYYELJSBYMXSXZTEMBBLLYYLLYTDQYSHYMRQWKFKBFXNXSBYCHXBWJYHTQBPBSBWDZYLKGZSKYHXQZJXHXJX"
        "GNLJKZLYYCDXLFYFGHLJGJYBXQLYBXQPQGZTZPLNCYPXDJYQYDYMRBESJYYHKXXSTMXRCZZYWXYQYBMCLLYZHQYZWQXDBXBZWZMS"
        "LPDMYSKFMZKLZCYQYCZLQXFZZYDQZPZYGYJYZMZXDZFYFYTTQTZHGSPCZMLCCYTZXJCYTJMKSLPZHYSNZLLYTPZCTZZCKTXDHXXT"
        "QCYFKSMQCCYYAZHTJPCYLZLYJBJXTPNYLJYYNRXSYLMMNXJSMYBCSYSYLZYLXJJQYLDZLPQBFZZBLFNDXQKCZFYWHGQMRDSXYCYT"
        "XNQQJZYYPFZXDYZFPRXEJDGYQBXRCNFYYQPGHYJDYZXGRHTKYLNWDZNTSMPKLBTHBPYSZBZTJZSZZJTYYXZPHSSZZBZCZPTQFZMY"
        "FLYPYBBJQXZMXXDJMTSYSKKBJZXHJCKLPSMKYJZCXTMLJYXRZZQSLXXQPYZXMKYXXXJCLJPRMYYGADYSKQLSNDHYZKQXZYZTCGHZ"
        "TLMLWZYBWSYCTBHJHJFCWZTXWYTKZLXQSHLYJZJXTMPLPYCGLTBZZTLZJCYJGDTCLKLPLLQPJMZPAPXYZLKKTKDZCZZBNZDYDYQZ"
        "JYJGMCTXLTGXSZLMLHBGLKFWNWZHDXUHLFMKYSLGXDTWWFRJEJZTZHYDXYKSHWFZCQSHKTMQQHTZHYMJDJSKHXZJZBZZXYMPAGQM"
        "STPXLSKLZYNWRTSQLSZBPSPSGZWYHTLKSSSWHZZLYYTNXJGMJSZSUFWNLSOZTXGXLSAMMLBWLDSZYLAKQCQCTMYCFJBSLXCLZZCL"
        "XXKSBZQCLHJPSQPLSXXCKSLNHPSFQQYTXYJZLQLDXZQJZDYYDJNZPTUZDSKJFSLJHYLZSQZLBTXYDGTQFDBYAZXDZHZJNHHQBYKN"
        "XJJQCZMLLJZKSPLDYCLBBLXKLELXJLBQYCXJXGCNLCQPLZLZYJTZLJGYZDZPLTQCSXFDMNYCXGBTJDCZNBGBQYQJWGKFHTNPYQZQ"
        "GBKPBBYZMTJDYTBLSQMPSXTBNPDXKLEMYYCJYNZCTLDYKZZXDDXHQSHDGMZSJYCCTAYRZLPYLTLKXSLZCGGEXCLFXLKJRTLQJAQZ"
        "NCMBYDKKCXGLCZJZXJHPTDJJMZQYKQSECQZDSHHADMLZFMMZBGNTJNNLGBYJBRBTMLBYJDZXLCJLPLDLPCQDHLXZLYCBLCXZZJAD"
        "JLNZMMSSSMYBHBSQKBHRSXXJMXSDZNZPXLGBRHWGGFCXGMSKLLTSJYYCQLTSKYWYYHYWXBXQYWPYWYKQLSQPTNTKHQCWDQKTWPXX"
        "HCPTHTWUMSSYHBWCRWXHJMKMZNGWTMLKFGHKJYLSYYCXWHYECLQHKQHTTQKHFZLDXQWYZYYDESBPKYRZPJFYYZJCEQDZZDLATZBB"
        "FJLLCXDLMJSSXEGYGSJQXCWBXSSZPDYZCXDNYXPPZYDLYJCZPLTXLSXYZYRXCYYYDYLWWNZSAHJSYQYHGYWWAXTJZDAXYSRLTDPS"
        "SYYFNEJDXYZHLXLLLZQZSJNYQYQQXYJGHZGZCYJCHZLYCDSHWSHJZYJXCLLNXZJJYYXNFXMWFPYLCYLLABWDDHWDXJMCXZTZPMLQ"
        "ZHSFHZYNZTLLDYWLSLXHYMMYLMBWWKYXYADTXYLLDJPYBPWUXJMWMLLSAFDLLYFLBHHHBQQLTZJCQJLDJTFFKMMMBYTHYGDCQRDD"
        "WRQJXNBYSNWZDBYYTBJHPYBYTTJXAAHGQDQTMYSTQXKBTZPKJLZRBEQQSSMJJBDJOTGTBXPGBKTLHQXJJJCTHXQDWJLWRFWQGWSH"
        "CKRYSWGFTGYGBXSDWDWRFHWYTJJXXXJYZYSLPYYYPAYXHYDQKXSHXYXGSKQHYWFDDDPPLCJLQQEEWXKSYYKDYPLTJTHKJLTCYYHH"
        "JTTPLTZZCDLTHQKZXQYSTEEYWYYZYXXYYSTTJKLLPZMCYHQGXYHSRMBXPLLNQYDQHXSXXWGDQBSHYLLPJJJTHYJKYPPTHYYKTYEZ"
        "YENMDSHLCRPQFDGFXZPSFTLJXXJBSWYYSKSFLXLPPLBBBLBSFXFYZBSJSSYLPBBFFFFSSCJDSTZSXZRYYSYFFSYZYZBJTBCTSBSD"
        "HRTJJBYTCXYJEYLXCBNEBJDSYXYKGSJZBXBYTFZWGENYHHTHZHHXFWGCSTBGXKLSXYWMTMBYXJSTZSCDYQRCYTWXZFHMYMCXLZNS"
        "DJTTTXRYCFYJSBSDYERXJLJXBBDEYNJGHXGCKGSCYMBLXJMSZNSKGXFBNBPTHFJAAFXYXFPXMYPQDTZCXZZPXRSYWZDLYBBKTYQP"
        "QJPZYPZJZNJPZJLZZFYSBTTSLMPTZRTDXQSJEHBZYLZDHLJSQMLHTXTJECXSLZZSPKTLZKQQYFSYGYWPCPQFHQHYTQXZKRSGTTSQ"
        "CZLPTXCDYYZXSQZSLXLZMYCPCQBZYXHBSXLZDLTCDXTYLZJYYZPZYZLTXJSJXHLPMYTXCQRBLZSSFJZZTNJYTXMYJHLHPPLCYXQJ"
        "QQKZZSCPZKSWALQSBLCCZJSXGWWWYGYKTJBBZTDKHXHKGTGPBKQYSLPXPJCKBMLLXDZSTBKLGGQKQLSBKKTFXRMDKBFTPZFRTBBR"
        "FERQGXYJPZSSTLBZTPSZQZSJDHLJQLZBPMSMMSXLQQNHKNBLRDDNXXDHDDJCYYGYLXGZLXSYGMQQGKHBPMXYXLYTQWLWGCPBMQXC"
        "YZYDRJBHTDJYHQSHTMJSBYPLWHLZFFNYPMHXXHPLTBQPFBJWQDBYGPNZTPFZJGSDDTQSHZEAWZZYLLTYYBWJKXXGHLFKXDJTMSZS"
        "QYNZGGSWQSPHTLSSKMCLZXYSZQZXNCJDQGZDLFNYKLJCJLLZLMZZNHYDSSHTHZZLZZBBHQZWWYCRZHLYQQJBEYFXXXWHSRXWQHWP"
        "SLMSSKZTTYGYQQWRSLALHMJTQJSMXQBJJZJXZYZKXBYQXBJXSHZTSFJLXMXZXFGHKZSZGGYLCLSARJYHSLLLMZXELGLXYDJYTLFB"
        "HBPNLYZFBBHPTGJKWETZHKJJXZXXGLLJLSTGSHJJYQLQZFKCGNNDJSSZFDBCTWWSEQFHQJBSAQTGYPQLBXBMMYWXGSLZHGLZGQYF"
        "LZBYFZJFRYSFMBYZHQGFWZSYFYJJPHZBYYZFFWODGRLMFTWLBZGYCQXCDJYGZYYYYTYTYDWEGAZYHXJLZYYHLRMGRXXZCLHNELJJ"
        "TJTPWJYBJJBXJJTJTEEKHWSLJPLPSFYZPQQBDLQJJTYYQLYZKDKSQJYYQZLDQTGJQYZJSUCMRYQTHTEJMFCTYHYPKMHYZWJDQFHY"
        "YXWSHCTXRLJHQXHCCYYYJLTKTTYTMXGTCJTZAYYOCZLYLBSZYWJYTSJYHBYSHFJLYGJXXTMZYYLTXXYPZLXYJZYZYYPNHMYMDYYL"
        "BLHLSYYQQLLNJJYMSOYQBZGDLYXYLCQYXTSZEGXHZGLHWBLJHEYXTWQMAKBPQCGYSHHEGQCMWYYWLJYJHYYZLLJJYLHZYHMGSLJL"
        "JXCJJYCLYCJPCPZJZJMMYLCQLNQLJQJSXYJMLSZLJQLYCMMHCFMMFPQQMFYLQMCFFQMMMMHMZNFHHJGTTHHKHSLNCHHYQDXTMMQD"
        "CYZYXYQMYQYLTDCYYYZAZZCYMZYDLZFFFMMYCQZWZZMABTBYZTDMNZZGGDFTYPCGQYTTSSFFWFDTZQSSYSTWXJHXYTSXXYLBYQHW"
        "WKXHZXWZNNZZJZJJQJCCCHYYXBZXZCYZTLLCQXYNJYCYYCYNZZQYYYEWYCZDCJYCCHYJLBTZYYCQWMPWPYMLGKDLDLGKQQBGYCHJ"
        "XY";;

QString pub::getStr(QString sour,QString sep,int ct)
{
    //sour: 源串
    //sep: 分隔符
    //ct: 返回被 sep 分隔的第 ct 个字串, 1 起始。
    if(sour.length() == 0)
    {
        //QMessageBox::information(NULL,"Note","pub::getStr:参数无效，源串不能为空！");
        qDebug()<<"pub::getStr:参数无效，源串为空\n";
        return "";
    }

    if(sep.length() == 0)
    {
        //QMessageBox::information(NULL,"Note","pub::getStr:参数无效，字串分隔符不能为空！");
        qDebug()<<"pub::getStr:参数无效，分隔符为空\n";
        return "";
    }

    if(ct < 1)
    {
        //QMessageBox::information(NULL,"Note","pub::getStr:参数无效，字序号不能小于1 ！");
        qDebug()<<"pub::getStr:参数无效，字序号小于1\n";
        return "";
    }

    QStringList strs = sour.split(sep);

    if(ct > strs.size() )
    {
        return "";
    }

    return strs.takeAt(ct - 1);
}

int pub::searchStr(QString sour,QString sep,QString dest)
{
    //sour: 源串
    //sep: 分隔符
    //dest: 目标字串
    //返回索引位置，1 起始
    //返回 0 表示未查到目录字串

    if(sour.length() == 0)
    {
        //QMessageBox::information(NULL,"Note","pub::searchStr:参数无效，源串不能为空！");
        qDebug()<<"pub::searchStr:参数无效，源串为空\n";
        return 0;
    }

    if(sep.length() == 0)
    {
        //QMessageBox::information(NULL,"Note","pub::searchStr:参数无效，字串分隔符不能为空！");
        qDebug()<<"pub::searchStr:参数无效，字串分隔符为空\n";
        return 0;
    }
    if(dest.length() == 0)
    {
        //QMessageBox::information(NULL,"Note","pub::searchStr:参数无效，目标字串不能为空！");
        qDebug()<<"pub::searchStr:参数无效，目标字串为空！\n";
        return 0;
    }

    QStringList strs = sour.split(sep);

    return strs.indexOf(dest) + 1;

}

QString pub::getYbStr(QString s, QString code)
{
    //入参：s 医保交易号， code 当前clinicCode
    QString sq;
    QString ret;
    qDebug()<<"申请医保交易流水号：交易代码，clinic_code"<<s<<code;
    sq = "call yb_jylsh('" + hos_ybbh + "','" + usr_code + "','" + s +"','"+ ybywzq + "','"+ code + "')";

    if(!qr.exec(sq)){
        QMessageBox::information(NULL,"Note","pub::getYbStr: SQL return error!");
        qDebug()<<sq;
        return "";
    }
    qr.next();
    ret = qr.value(0).toString();
    if(ret.isEmpty()){
        QMessageBox::information(NULL,"Note","申请医保交易流水号错误!");
        return "";
    }
    ret = s + "^" + hos_ybbh + "^" + usr_code + "^" + ybywzq + "^" + ret + "^0000^";
    ybywzqAtinc = qr.value(1).toString();   //申请交易流水的atinc，待补全中心返回交易流水用。
    qDebug()<<"申请成功。 ybywzqAtinc"<<ybywzqAtinc;
    return ret;
}
QString pub::getDicN(QString dic_type, QString code)   //查字典，由码查名 mysql
{
    if(!qr.exec("select name from com_dict_com where dic_type = '"+dic_type+"' "
                " and valid_flag = '1' and code = '"+code+"'"))
    {
        return "";
    }
    if(!qr.next())
    {
        return "";
    }
    return qr.value(0).toString();
}

QString pub::getDicC(QString dic_type, QString name)   //查字典，由名查码 mysql
{
    if(!qr.exec("select code from com_dict_com where dic_type = '"+dic_type+"' "
                " and valid_flag = '1' and name = '"+name+"'"))
    {
        return "";
    }
    if(!qr.next())
    {
        return "";
    }
    return qr.value(0).toString();
}

QString pub::getDicN_o(QString dic_type, QString code, QSqlQuery *qrt)   //查字典，由码查名 oracle
{
    if(!qrt->exec("select name from com_dictionary where type = '"+dic_type+"' "
                  "and valid_state = '1' and code = '"+code+"'"))
    {
        return "";
    }
    if(!qrt->next())
    {
        return "";
    }
    return qrt->value(0).toString();
}

QString pub::getDicC_o(QString dic_type, QString name, QSqlQuery *qrt)   //查字典，由名查码 oracle
{
    if(!qrt->exec("select code from com_dictionary where type = '"+dic_type+"' "
                  " and valid_state = '1' and name = '"+name+"'"))
    {
        return "";
    }
    if(!qrt->next())
    {
        return "";
    }
    return qrt->value(0).toString();
}

QString pub::getYbStrJ(QString s, QString code)
{
    //

    QString sq;
    QString ret;
    //qDebug()<<"申请医保交易流水号：交易代码，clinic_code"<<s<<code;
    sq = "call yb_jylshj('" + hos_ybbh + "','" + usr_code + "','" + s +"','ybywzq','"+ code + "')";

    if(!qr.exec(sq)){
        //QMessageBox::information(NULL,"Note","pub::getYbStrJ: SQL return error!");
        qDebug()<<sq;
        return "";
    }

    qr.next();
    ret = qr.value(0).toString();
    if(ret.isEmpty())
    {
        qDebug()<<s + " in ybGetStrJ 申请医保交易流水号错误!";
        //QMessageBox::information(NULL,"Note", s + " in ybGetStrJ 申请医保交易流水号错误!");
        return "";
    }
    //ret = s + "^" + hos_ybbh + "^" + usr_code + "^" + ybywzq + "^" + ret + "^0000^";
    ybywzqAtinc = qr.value(1).toString();   //申请交易流水的atinc，待补全中心返回交易流水用。
    //qDebug()<<"申请成功。 ybywzqAtinc"<<ybywzqAtinc;
    return ret;
}

QStringList pub::getNl(QString s)
{
    QStringList ret;
    int strLen = s.length();
    if( strLen != 8 && strLen != 10){
        QMessageBox::information(NULL,"错误","年龄转换输入参数长度不正确："+s);
        ret<<"0"<<"天";
        return ret;
    }

    QDate cDate = QDate().currentDate();
    QDate sDate;
    if(strLen == 8){
        sDate = QDate().fromString(s,"yyyyMMdd");
    }else{
        sDate = QDate().fromString(s,"yyyy/MM/dd");
        if(!sDate.isValid()){
            sDate = QDate().fromString(s,"yyyy-MM-dd");
            if(!sDate.isValid()){
                QMessageBox::information(NULL,"错误","年龄转换输入无效日期："+s);
                ret<<"0"<<"天";
                return ret;
            }
        }
    }


    //QDate sDate = QDate().fromString(s);
    if(!sDate.isValid()){
        QMessageBox::information(NULL,"错误","年龄转换输入无效日期："+s);
        ret<<"0"<<"天";
        return ret;
    }
    int day = sDate.daysTo(cDate);
    if(day > 365 ){
        ret << QString::number(int(day/365))<<"岁";
    }else if(day>30){
        ret << QString::number(int(day/30))<<"月";
    }else if(day>=0){
        ret << QString::number(day)<<"天";
    }else{
        QMessageBox::information(NULL,"错误","年龄转换输入日期大于当前日期："+s);
    }
    return ret;
}

QString pub::getBirth(QString s)
{
    QDate cDate ;
    QRegExp re;
    int day ;

    re = QRegExp("^[1-9]\\d*[岁|月|天]?$");
    if(!re.exactMatch(s))
    {
        QMessageBox::information(NULL,"错误","年龄输入格式不正确："+s);
        return "";
    }
    re = QRegExp("^[1-9]\\d*");
    re.indexIn(s);
    day = re.cap().toInt();

    if( day > 150)
    {
        //不应出现大于150岁的年龄
        QMessageBox::information(NULL,"错误","年龄大于最大合理范围！");
        return "";
    }

    re = QRegExp("[岁|月|天]*$");
    re.indexIn(s);
    QString u = re.cap();
    u = u.isEmpty() ? "岁" : u;

    if( u == "岁" )
    {
        day = day * 365.3;
    }
    else if( u == "月")
    {
        day = day * 30.5;
    }

    cDate = QDate().currentDate().addDays( 0 - day);

    return cDate.toString("yyyyMMdd");
}

QString pub::add0(QString s, int len)//增加数字前导0
{
    for(int c = s.length(); c < len; c ++ )
    {
        s = "0" + s;
    }
    return s;
}

QString pub::bigW(float x)   //数字转大写
{
    QRegExp re ;
    QString ret,base,base2,lead;
    base="零壹贰叁肆伍陆柒捌玖拾";
    base2="万仟佰拾元角分";
    //负数的处理
    if(x+0.0001<0){
        lead="负";
        x=0-x;
    }else{
        lead="";
    }
    int yuan = 0, j = 0, f = 0;		//元角分
    QString xx = QString::asprintf("%.2f", x); //浮点转字串

    re = QRegExp("^[1-9]\\d*"); //匹配前导数字
    re.indexIn(xx);
    yuan = re.cap().toInt();
    re = QRegExp(".\\d*$"); //匹配末尾数字
    re.indexIn(xx);
    QString jf = re.cap();  //含小数点的角分
    j = jf.mid(1,1).toInt();
    f = jf.mid(2,1).toInt();

    int tmpUp,tmpDown,big,count;
    bool appear0=false;//0标志
    bool start=false;		//转换开始标志
    big=10000;
    count=0;
    //整数部分
    while(big>0){
        tmpUp = yuan / big;		    //取当前最高位数
        tmpDown = yuan % big;		//取余数
        yuan=tmpDown;
        if(tmpUp>0){                //当前位数大于0
            ret=ret+base.mid(tmpUp,1)+base2.mid(count,1);
            start=true;
            appear0=false;
        }
        if(start){		//高位 0 已经全部排除
            if(tmpUp==0 && big==10000){
                ret=ret+"万";
            }
            if(tmpUp==0 && tmpDown == 0 && j==0 && f == 0){	//此后无有效数位
                if(big>=10000){
                    ret=ret+"万元";
                }else{
                    ret=ret+"元";
                }
                break;
            }else if(tmpUp==0 && tmpDown ==0 && (j>=0 || f>0 )){
                //此后无有效整数位，但有角分
                ret=ret+"元零";
                //0标记，用于小数位打印。循环退出之前设置，不会对下个判断造成干扰
                appear0=true;
                break;
            }else if(!appear0 && tmpUp==0 && tmpDown >0 ){
                //连续 0 中的第 1 个 ，此后还有有效整数位
                ret=ret+"零";
                appear0=true;
            }
        }
        big/=10;
        count++;
    }
    //小数部分
    if(j != 0 || f!= 0){		//角不为 0  或分不为 0
        if( j==0 ){		//角为0
            if( !appear0 ){     //最后整数位非零
                ret=ret+"零";
            }
            //角为 0 ，最后整数位已经有零则不需要处理
        }else {
            ret=ret+base.mid(j,1)+"角";
        }
        ret=ret+base.mid(f,1)+"分";
    }else{
        ret=ret+"整";
    }
    if(ret == "整"){
        ret = "零元";
    }
    return lead+ret;
}

QString pub::getValueFromList(QStringList lst, QString str)
{
    QString ret = "";
    foreach(QString i, lst){
        if(pub::getStr(i,"^",1) == str){
            ret = pub::getStr(i,"^",2);  //
            break;
        }
    }
    return ret;
}

bool pub::call_business(QString busi_code, QJsonObject &input, QString &info, //QString &currentMsgid,
                        QJsonObject &jsonRet, QString fileName , bool saveOut,
                        QNetworkAccessManager &manager, QNetworkRequest &request,
                        QString clinic_code)
{

    //elps.start();

    //申请交易流水号
    QString currentMsgid = pub::getYbStrJ(busi_code, clinic_code);   //
    if(currentMsgid.isEmpty())
    {
        info = "申请交易流水号失败！";
        return false;
    }

    QJsonObject in; //最终入参
    in.insert("input", input);


    //入参必须基本内容
    in.insert("infno", busi_code);
    in.insert( "msgid", currentMsgid);
    in.insert("mdtrtarea_admvs", pub::hos_insuplc);
    //in.insert("insuplc_admdvs", mpPerson["insuplc_admdvs"] );
    in.insert("insuplc_admdvs","210100");
    in.insert("recer_sys_code", "OwnSoft");
    in.insert("dev_no","");
    in.insert("dev_safe_info","");
    in.insert("cainfo", pub::hos_secretcode);
    in.insert("signtype","");
    in.insert("infver", "V1.0");
    in.insert("opter_type", "1");
    in.insert("opter", pub::usr_code);
    in.insert("opter_name", pub::usr_name);
    in.insert("inf_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
    in.insert("fixmedins_code", pub::hos_ybbh);
    in.insert("fixmedins_name", pub::hos_name);
    in.insert("sign_no", pub::sign_no);

    QJsonDocument indoc ;   //入参从object转为document
    indoc.setObject(in);

    //保存入参日志
    QString sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qr.exec(sq))
    {
        qDebug()<<  busi_code + " 保存入参日志失败";

    }


    QNetworkReply* reply = manager.post(request, indoc.toJson());

    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回

    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        info = "http 请求状态错误: " + statusCode.toString();
        QString s = "update com_business set tmstmp = now(), infcode = -2, v_out = '"
                + info + "' where jyls = '" + currentMsgid + "'";
        qr.exec(s);
        qDebug()<<"请求状态错误"<<s;
        return false;
    }

    QNetworkReply::NetworkError err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        info = "NetworkReply 返回状态错误：" + reply->errorString();
        QString s = "update com_business set tmstmp = now(),infcode = -3, v_out = '"
                + info + "' where jyls = '" + currentMsgid + "'";
        qr.exec(s);
        qDebug()<<"返回状态错误："<<s;
        return false;
    }

    // 获取MIME类型和字符集
    QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
    QString charset = contentType.split("charset=").last();
    QString encoding = (charset.isEmpty()
                        || charset == "application/octet-stream")
            ? "UTF-8"
            : charset; // 默认使用UTF-8编码

//    qDebug()<<"busi code is : "<<busi_code;
//    qDebug()<<"contentType:"<<contentType;
//    qDebug()<<"charset:"<<charset;
//    qDebug()<<"encoding:"<<encoding;

    QByteArray bt = reply->readAll();

    if(!fileName.trimmed().isEmpty())
    {
        QString flnm = downloadPath + "/" + fileName.trimmed();

        QFile f(flnm);
        if(f.exists())
        {
            f.remove();
        }

        if(!f.open(QIODevice::WriteOnly)){
            QMessageBox::information(NULL, "注意", "建立下载文件失败！");
            qr.exec("update com_business set tmstmp = now(),infcode = -4, "
                    " v_out = '建立下载文件失败' where jyls = '" + currentMsgid + "'");
            return false;
        }

        f.write(bt);
        f.close();

        //文件下载，如体积小于1k，进行有效性验证

        if(bt.size() < 1024 )
        {
            QString t ;
            if(encoding == "UTF-8")
            {
                t = QString::fromUtf8(bt);
            }
            else
            {
                t = QString::fromLocal8Bit(bt);
            }
            //QString

            QJsonParseError json_error;
            QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
            if(json_error.error != 0 )
            {
                //json数据解析失败，数据内容应该是压缩包
                //不保存出参，只保存完成时间
                sq = "update com_business set tmstmp = now()  , infcode = "
                        + QString::number(jsonRet.value("infcode").toInt())
                         +  " where jyls = '" + currentMsgid + "'";
                if(!qr.exec(sq))
                {
                    qDebug()<<  busi_code + " 保存出参日志失败！";
                    qDebug()<<sq;
                }
                return true;
            }

            //解析json成功，一定是文件下载出错。
            jsonRet = jsdc.object();

            sq = "update com_business set tmstmp = now(),   v_out = '"
                    + jsdc.toJson(QJsonDocument::Compact)
                    + "' , infcode = "
                    + QString::number(jsonRet.value("infcode").toInt())
                    +  "  where jyls = '" + currentMsgid + "'";

            if(!qr.exec(sq))
            {
                qDebug()<<  busi_code + " 保存出参日志失败！";
                qDebug()<<sq;
            }

            info = busi_code + " 交易失败：" + jsonRet.value("err_msg").toString() ;
            return false ;

        }

        return true;
    }

    QString t ;
    if(encoding == "UTF-8")
    {
        t = QString::fromUtf8(bt);
    }
    else
    {
        t = QString::fromLocal8Bit(bt);
    }
    //QString

    QJsonParseError json_error;
    QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        info = "返回信息Json解析错误 " + json_error.errorString();
        qr.exec("update com_business set tmstmp = now(),infcode = -5, "
                "v_out = '" + info + "' where jyls = '" + currentMsgid + "'");
        return false;
    }
    //qDebug()<< " outDoc : "<<jsdc;

    jsonRet = jsdc.object();

    if(saveOut) //是否需要保存出参
    {
        QString out_str = jsdc.toJson(QJsonDocument::Compact);
        out_str.replace("'","\\'");

        sq = "update com_business set tmstmp = now(),   v_out = '"
                + out_str
                + "' , infcode = "
                + QString::number(jsonRet.value("infcode").toInt())
                 +  "  where jyls = '" + currentMsgid + "'";
    }
    else
    {
        //不保存出参，只保存完成时间
        sq = "update com_business set tmstmp = now()  , infcode = "
                + QString::number(jsonRet.value("infcode").toInt())
                 +  " where jyls = '" + currentMsgid + "'";
    }

    if(!qr.exec(sq))
    {
        qDebug()<<  busi_code + " 保存出参日志失败！";
        qDebug()<<sq;
    }

    if(jsonRet.value("infcode").toInt() != 0)
    {
        info = busi_code + " 交易失败：" + jsonRet.value("err_msg").toString() ;
        return false ;
    }

    return true;
}

QString pub::getFirstLetters(QString strText)
{

    if( strText.length() == 0 )
    {
        return strText ;
    }
    QString myStr;
    int index=0;
    for( int i=0;i<strText.length();i++)
    {
        // 若是字或数字则直接输出

        ushort vChar=strText[i].unicode() ;
        if( ( vChar >= 'a' && vChar <='z' ) || ( vChar >='A' && vChar <='Z' ) )
            myStr.append(strText[i].toUpper() );
        if( ( vChar >='0' && vChar <='9' ) )

            myStr.append(strText[i]) ;
        else
        {
            index = (int)vChar - 19968 ;

            if( index >= 0 && index < strChineseFirstPY.length() )
                myStr.append( strChineseFirstPY[index]);
        }

    }
    return myStr ;
}

void pub::setColumnWidth(QTableView * tb, QString col_width, int tab_width, int col_count)
{
    //表，列宽定义，表宽，总列数量
    for(int i = 0; i< col_count; i++)
    {
        double w = getStr( col_width, "^", i + 1).toDouble();
        tb->setColumnWidth(i, w * tab_width);
    }

}

bool pub::verifyIdCard(const char* idCard)
{
    if(strlen(idCard) != 18)
    {    //检测当前身份证是否为18位
        return false;
    }
    else
    {
        int coefficient[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};                //身份证前17位对应的系数列表
        char checkCodeList[] = {'1','0','X','9','8','7','6','5','4','3','2'};    //余数所对应的效验码列表
        int Sum = 0;
        int remainder;
        char checkCodeValue;

        for(int i=0;i<17;++i)
        {
            Sum += (idCard[i]-48) * coefficient[i];   //身份证前17位分别与对应的系数相乘之和
        }

        remainder = Sum % 11;  //取余数
        checkCodeValue = checkCodeList[remainder];    //余数只会是[0,10] 计算得到身份证最后一位 效验码

        if(checkCodeValue == 'X')
        {  //用于效验码是'X'的一些处理
            if(checkCodeValue == std::toupper(idCard[17]))
            {
                return true;
            }else{
                return false;
            }
        }else{
            if(checkCodeValue == idCard[17])
            {
                return true;
            }else{
                return false;
            }
        }
    }
}

QString pub::fillCombo(QComboBox *cbb, QString sq , int ind, bool clr )
{
    //按 sq 提取数据，填充下拉列表 cbb, 填充之后索引指向 ind, ind = 999 定位到最末记录
    //返回一个 QString 形式的列表内容
    //clr确定填充列表之前是否清除旧数据

    QString retVal; //返回值
    //int count = 0;
    qDebug()<<sq;
    if(!qr.exec(sq))
    {
        QMessageBox::information( NULL, "注意", "检索 comboBox 记录失败！\nerrmsg : "
                                 + qr.lastError().text()+"\nsql : "+sq);
        return "";
    }

    if(clr)
    {
        cbb->clear();
    }

    while(qr.next())
    {
        //count ++;
        cbb->addItem(qr.value(0).toString());
        for(int i = 0; i < qr.record().count() ;i++)
        {
            retVal += qr.value(i).toString() + "^";
        }
        //qDebug()<<qr.value(0).toString()<<","<<qr.value(1).toString();;
    }
    //qDebug()<<"count is "<<QString::number(count);
    //qDebug()<<retVal;
    if(ind == 999)
    {
        cbb->setCurrentIndex( cbb->count() - 1 );
    }
    else
    {
        cbb->setCurrentIndex(ind);
    }

    return retVal;
}

QString pub::fillCombo(QComboBox *cbb, QString sq , int ind, QSqlQuery * qrt, bool clr )    //填充下拉列表
{
    //按 sq 提取数据，填充下拉列表 cbb, 填充之后索引指向 ind, ind = 999 定位到最末记录
    //返回一个 QString 形式的列表内容
    //clr确定填充列表之前是否清除旧数据

    QString retVal = ""; //返回值
    //int count = 0;
    if(!qrt->exec(sq))
    {
        QMessageBox::information( NULL, "注意", "检索 comboBox 记录失败！\nerrmsg : "
                                 + qrt->lastError().text()+"\nsql : "+sq);
        return "";
    }

    if(clr)
    {
        cbb->clear();
    }

    while(qrt->next())
    {
        //count ++;
        cbb->addItem(qrt->value(0).toString());
        for(int i = 0; i < qrt->record().count() ;i++)
        {
            retVal += qrt->value(i).toString() + "^";
        }
    }

    if(ind == 999)
    {
        cbb->setCurrentIndex( cbb->count() - 1 );
    }
    else
    {
        cbb->setCurrentIndex(ind);
    }

    return retVal;

}


void pub::printOutExcel(QJsonObject &js, int print_times)
{
    /*
    jsonarray 参数结构
    {
        //处理模式  "p" 打印， "s" 保存， "ps" 打印且保存, 默认为 "p"
        process_mode : string

        //模板文件名称
        model_name : string

        //划表线区域
        grid_range : [{ range : string }]

        //需要合并的区域
        merge_range : [{ range : string }]

        //需要单独设定的列宽
        col_width : [{ range : string , width : int}]

        //需要单独设定的行高
        row_height : [{ range : string , height : int}]

        //需要清除内容的区域
        clear_range : [{ row1 : num, col1 : num, row2 : num, col2 : num }]

        //单元格数据
        cell_value : [{ row : num, col : num, val : string }]
    }
    */



    //提取参数中的数据进行处理

    QJsonArray jsa_val = js.value("cell_value").toArray();    //打印数据
    QJsonArray jsa_clr = js.value("clear_range").toArray();    //预清除区域
    QJsonArray jsa_grd = js.value("grid_range").toArray();    //画线区域
    QJsonArray jsa_merge = js.value("merge_range").toArray();    //需要合并的区域
    QJsonArray jsa_col_w = js.value("col_width").toArray();    //需要单独设定的列宽
    QJsonArray jsa_row_h = js.value("row_height").toArray();    //需要单独设定的行高


    QString model_file, temp_file, dest_file; //模版文件, 临时文件，目标文件
    model_file = QCoreApplication::applicationDirPath();
    temp_file = QCoreApplication::applicationDirPath();
    dest_file = pub::downloadPath;               //目标文件位于下载路径

    dest_file.append("/" + pub::usr_name + "-" + QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + ".xls");
    temp_file.append("/tmp.xls");

    QFile old_file(temp_file);
    if(old_file.exists() && !old_file.remove())
    {
        QMessageBox::information(NULL, "注意", "无法移除旧的报表临时文件！");
        return;
    }

    model_file.append( js.value("excel_model").toString() );

    QFile fl(model_file);
    if(!fl.exists())
    {
        QMessageBox::information(NULL, "注意", "报表模板文件不存在！");
        return;
    }

    if(!fl.copy(temp_file))
    {
        QMessageBox::information(NULL, "注意", "拷贝模版文件失败！");
        return;
    }


    //调整系统默认打印机
    //api 函数原型
    typedef BOOL __stdcall (*pGetDefaultPrinter)(LPTSTR , LPDWORD);//
    typedef BOOL __stdcall (*pSetDefaultPrinter)(LPTSTR);//
    pGetDefaultPrinter getPrinterName = NULL;
    pSetDefaultPrinter setPrinterName = NULL;

    bool err = true;    //api 函数有效性标志
    QLibrary lib;
    QFile f;
    QString dllFile = QCoreApplication::applicationDirPath();
    dllFile.append("/winspool.dll");

    if(f.exists(dllFile) ){ //态库存在且允许使用
        lib.setFileName("winspool");
        if(lib.load())
        {
            getPrinterName  = (pGetDefaultPrinter)lib.resolve("GetDefaultPrinterA");//
            setPrinterName = (pSetDefaultPrinter)lib.resolve("SetDefaultPrinterA") ;//

            if(getPrinterName != NULL && setPrinterName != NULL)
            {
                err = false;
            }
        }
    }

    QSettings setIni("clin.ini", QSettings::IniFormat);
    QString newPrName = setIni.value("bz/printer").toString();    //
    QString curPrName;
    bool printer_changed = false;

    if(err)
    {
        QMessageBox::information(NULL, "注意","winspool.dll 无效，将使用系统默认打印机输出！");
    }
    else
    {
        char prtName[256];
        DWORD sz = 256;
        if(!getPrinterName((LPTSTR)prtName, (LPDWORD)&sz))
        {
            QMessageBox::information(NULL, "注意","无法获取系统当前打印机名称！");
        }
        else
        {
            curPrName = QString(prtName);

            if(!setPrinterName((LPTSTR)newPrName.toLatin1().data()))
            {
                QMessageBox::information(NULL, "注意","系统将以当前默认打印机输出！");
            }
            else
            {
                printer_changed = true;
            }
        }
    }


    QAxObject *excel;   //操作excel用于打印输出


    excel = new QAxObject("Ket.Application"); //
    qDebug()<<" 尝试启动 wps 电子表...\n";

    if(excel->isNull())
    {

        excel = new QAxObject("Excel.Application"); //
        qDebug()<<"  尝试启动 excel 电子表...\n";
        if(excel->isNull())
        {
            QMessageBox::information(NULL, "错误", "电子表启动失败！");
            return;
        }
    }

    excel->dynamicCall("SetVisible (bool Visible)", "false"); // 设置为不显示窗体
    excel->setProperty("DisplayAlerts", false); //不显示任何警告信息

    QAxObject *wkBooks = excel->querySubObject("Workbooks");
    wkBooks->dynamicCall("Open(const QString&)", temp_file);
    QAxObject *book =  excel->querySubObject("ActiveWorkBook");
    QAxObject *wkSheets = book->querySubObject("WorkSheets");
    QAxObject *sheet = wkSheets->querySubObject("Item(int)", 1);
    QAxObject *cell  ;//= new QAxObject ;

    //表格画线
    for(int i = 0; i < jsa_grd.size(); i++)
    {

        QJsonObject jo = jsa_grd[i].toObject();
        QAxObject *range = sheet->querySubObject("Range(const Qvariant&)", QVariant(QString(jo.value("range").toString())));

        //区域内部水平框线
        QAxObject* borders_inside_hor = range->querySubObject("Borders(xlInsideHorizontal)");
        //区域内部垂直框线
        QAxObject* borders_inside_ver = range->querySubObject("Borders(xlInsideVertical)");
        //左边框线
        QAxObject* borders_left = range->querySubObject("Borders(xlEdgeLeft)");
        //右边框线
        QAxObject* borders_right = range->querySubObject("Borders(xlEdgeRight)");
        //顶边框线
        QAxObject* borders_top = range->querySubObject("Borders(xlEdgeTop)");
        //下边框线
        QAxObject* borders_bottom = range->querySubObject("Borders(xlEdgeBottom)");

        QList<QAxObject*> border_list = {borders_inside_hor, borders_inside_ver, borders_left, borders_right, borders_top, borders_bottom};
        for (auto& one : border_list) {
            one->setProperty("LineStyle",1);//设置线型实线
            one->setProperty("Weight",2);//设置宽度
            //one->setProperty("ColorIndex",1);
            //one->setProperty("Color", QColor(0, 0, 0));//设置颜色
        }
    }

    //需要合并的区域
    for(int i = 0; i < jsa_merge.size(); i++)
    {
        QJsonObject jo = jsa_merge[i].toObject();
        QAxObject *range = sheet->querySubObject("Range(const Qvariant&)", QVariant(QString(jo.value("range").toString())));
        range->setProperty("MergeCells", 1);
    }

    //range->setProperty("VerticalAlignment", -4108);     // 水平居中
    //range->setProperty("HorizontalAlignment", -4108);   // 垂直居中

    //需要单独设定的列宽
    for(int i = 0; i < jsa_col_w.size(); i++)
    {
        QJsonObject jo = jsa_col_w[i].toObject();
        QAxObject *range = sheet->querySubObject("Range(const Qvariant&)", QVariant(QString(jo.value("range").toString())));
        int default_width = range->dynamicCall("ColumnWidth").toInt();
        qDebug()<<"default_width : "<<QString::number(default_width);
        //range->setProperty("ColumnWidth", jo.value("width").toInt());
        range->setProperty("ColumnWidth", default_width * 1.5);

    }

    //需要单独设定的行高
    for(int i = 0; i < jsa_row_h.size(); i++)
    {
        QJsonObject jo = jsa_row_h[i].toObject();
        QAxObject *range = sheet->querySubObject("Range(const Qvariant&)", QVariant(QString(jo.value("range").toString())));
        range->setProperty("RowHeight", jo.value("height").toInt());
    }

    //清空表格
    for(int i = 0; i < jsa_clr.size(); i++)
    {
        QJsonObject jo = jsa_clr[i].toObject();
        int row , col;
        for(row = jo.value("row1").toInt(); row < jo.value("row2").toInt(); row ++)
        {
            for(col = jo.value("col1").toInt(); col < jo.value("col2").toInt(); col++)
            {
                cell = sheet->querySubObject("Cells(int, int)", row, col);
                cell->dynamicCall("SetValue(const QVariant&)",QVariant(""));
                //cell->setProperty("Value", "");
            }
        }
    }

    //向表格写入数据
    for(int i = 0; i < jsa_val.size(); i++)
    {
        QJsonObject jo = jsa_val[i].toObject();
        //sheet->querySubObject("Range(const Qvariant&)", QVariant(QString(jo.value("range").toString())));
        cell = sheet->querySubObject("Cells(int, int)", jo.value("row").toInt(), jo.value("col").toInt());//
        cell->dynamicCall("SetValue(const QVariant&)",QVariant(jo.value("val").toString()));
        //cell->setProperty("Value", jo.value("val").toString());
    }

    QString md = js.value("process_mode").toString();  //报表模式

    QFile fl_tmp(temp_file);

    if(md == "ps" || md == "s")
    {
        book->dynamicCall("Save()");    //保存
        if(fl_tmp.copy(dest_file))
        {
            QString path = QDir::currentPath();
            QMessageBox::information(NULL, "注意", "报表文件已生成，路径为 " + path.mid(0, 2) + dest_file + "。");
        }
        else
        {
            QMessageBox::information(NULL, "注意", "复制目标文件失败！");
        }

        if(md == "ps")
        {
            for(int i = 0; i < print_times; i++ )
            {
                book->dynamicCall("PrintOut()");   //打印输出
            }
        }

    }
    else  //默认为打印
    {
        for(int i = 0; i < print_times; i++ )
        {
            book->dynamicCall("PrintOut()");   //打印输出
        }
    }

    book->dynamicCall("Close(Boolean)", false);  // 关闭文件
    excel->dynamicCall("Quit()"); // 关闭excel

    if(printer_changed)
    {
        if(!setPrinterName((LPTSTR)curPrName.toLatin1().data()))
        {
            QMessageBox::information(NULL, "注意","系统当前打印机已变更，请手动改回！");
        }
    }

    delete excel;

    if(md != "ps" && md != "s")
    {
        QMessageBox::information(NULL, "注意", "数据处理完毕！");
    }

}


int pub::check_system_time() //检查本机时间与服务器时间差
{
    QString sq = "select now() from dual";
    if(!qr.exec(sq))
    {
        qDebug()<<"sql error : "<<qr.lastError().text();
    }
    QDateTime server_dt = qr.value(0).toDateTime();
    qr.next();
    server_dt = qr.value(0).toDateTime();
    qDebug()<<"server_dt is "<<server_dt.toString();
    QDateTime local_dt = QDateTime::currentDateTime();
    qDebug()<<"local_dt is "<<local_dt.toString();
    int ret_var = server_dt.secsTo(local_dt);

    return ret_var ;
}

void pub::export_sql_to_excel(QString sq, QSqlQuery * qr)
{
    if(!qr->exec(sq))
    {
        QMessageBox::information(NULL, "注意", "SQL 语句无效！\n" + sq);
        qDebug()<<"export_sql_to_excel sql ： "<<sq;
        return;
    }

    QSqlRecord rcd = qr->record();     //为提取字段标题

    QJsonDocument d;
    QJsonArray jsa_val;    //数值

    QJsonObject jot;  // 临时json
    int row = 1;

    int rowCount = 0;
    //int columnCount = 0;

    //提取字段名称
    for(int i = 0; ; i++)
    {
        if(rcd.fieldName(i).isEmpty())
        {
            //columnCount = i;
            break;
        }
        else
        {
            QString itm = rcd.fieldName(i);

            jot.insert("val", itm);
            jot.insert("row", row);
            jot.insert("col", i + 1 );
            jsa_val << jot;
        }
    }

    row++;

    while(qr->next())
    {
        rcd = qr->record();

        for(int i = 0; ; i++)
        {
            if(rcd.fieldName(i).isEmpty())
            {
                break;
            }
            else
            {
                QString itm = rcd.value(i).toString();

                jot.insert("val", itm);
                jot.insert("row", row);
                jot.insert("col", i + 1 );
                jsa_val << jot;
            }
        }

        row ++;
        rowCount ++ ;

    }

    QJsonObject jo;
    jo.insert("excel_model", "/sheets/empty.xls");
    jo.insert("cell_value", jsa_val);
    jo.insert("process_mode", "s"); //只保存，不打印

    printOutExcel(jo);
}

bool pub::isAlmostEqual(double a, double b, double epsilon )
{
    return std::abs(a - b) < epsilon;
}

bool pub::get_db_connect(QString mode)
{
    /*
    bool db_OK = true;

    if(!pub::db_m.isOpen())
    {
        qDebug()<<"database connection is losed...\n";
        if(!get_db_connect())
        {
            qDebug()<<"connection database return error.\n";
            //return;
             db_OK = false;
        }
    }
    else
    {
        qDebug()<<"database has opened and connected.\n";
    }

*/

    //mode : m,mysql  o,oracle   a,all

    QSettings setIni("clin.ini", QSettings::IniFormat);
    QString host,port,dbnm, usr, pswd;

    if(mode == "m" || mode == "a" )
    {
        host = setIni.value("database/m_hostname").toString();
        port = setIni.value("database/m_port").toString();
        dbnm = setIni.value("database/m_databasename").toString();
        usr = setIni.value("database/m_username").toString();
        pswd = setIni.value("database/m_password").toString();

        pub::db_m.setPort(port.toInt());
        pub::db_m.setHostName(host);
        pub::db_m.setPassword(pswd);
        pub::db_m.setUserName(usr);
        pub::db_m.setDatabaseName(dbnm);
        pub::db_m.setConnectOptions("MYSQL_OPT_CONNECT_TIMEOUT=8");

        if(!pub::db_m.open())
        {
            qDebug()<<"Open database mysql failed.\n";
            return false;
        }
    }

    if(mode == "o" || mode == "a" )
    {
        host = setIni.value("database/o_hostname").toString();
        port = setIni.value("database/o_port").toString();
        dbnm = setIni.value("database/o_databasename").toString();
        usr = setIni.value("database/o_username").toString();
        pswd = setIni.value("database/o_password").toString();

        pub::db_o.setPort(port.toInt());
        pub::db_o.setHostName(host);
        pub::db_o.setPassword(pswd);
        pub::db_o.setUserName(usr);
        pub::db_o.setDatabaseName(dbnm);

        if(!pub::db_o.open())
        {
            qDebug()<<"Open database oracle failed.\n";
            return false;
        }
    }

    QString str_display = "Database connected at " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

    qDebug()<<str_display<<"\n";

    return true;
}

bool pub::call_busi_push(QString busi_code, QJsonObject &input, QString &info, //QString &currentMsgid,
                        QJsonObject &jsonRet, QString fileName , bool saveOut,
                        QNetworkAccessManager &manager, QNetworkRequest &request,
                        QString clinic_code)
{

    //向平台推送消息
    //elps.start();

    //申请交易流水号
    QString currentMsgid = pub::getYbStrJ(busi_code, clinic_code);   //
    if(currentMsgid.isEmpty())
    {
        info = "申请交易流水号失败！";
        return false;
    }

    QJsonObject in; //最终入参
    QJsonDocument str_jsdc(input);
    QString str_input = QString(str_jsdc.toJson(QJsonDocument::Compact));
    in.insert("encData", str_input);
//qDebug()<<"input"<<input;
//qDebug()<<"str_jsdc"<<str_jsdc;
//qDebug()<<"str_input"<<str_input;

    //入参必须基本内容
    in["signData"] = "";
    in["encType"] = "plain";
    in["appId"] = pub::app_id;
    in["signType"] = "sm2";
    in["version"] = "2.0.1";
//    in["timestamp"] = QDateTime::currentDateTime().toString("yyyyMMddHHmmss");
    in["timestamp"] = QDateTime::currentDateTime().toMSecsSinceEpoch();

    QJsonDocument indoc ;   //入参从object转为document
    indoc.setObject(in);

    //保存入参日志
    QString sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qr.exec(sq))
    {
        qDebug()<<  busi_code + " 保存入参日志失败";

    }
//    qDebug()<<"indoc"<<indoc;
//    qDebug()<<"indoc.toJson()"<<indoc.toJson();

    QNetworkReply* reply = manager.post(request, indoc.toJson());

    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回

    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        info = "http 请求状态错误: " + statusCode.toString();
        QString s = "update com_business set tmstmp = now(), infcode = -2, v_out = '"
                + info + "' where jyls = '" + currentMsgid + "'";
        qr.exec(s);
        qDebug()<<"请求状态错误"<<s;
        return false;
    }

    QNetworkReply::NetworkError err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        info = "NetworkReply 返回状态错误：" + reply->errorString();
        QString s = "update com_business set tmstmp = now(),infcode = -3, v_out = '"
                + info + "' where jyls = '" + currentMsgid + "'";
        qr.exec(s);
        qDebug()<<"返回状态错误："<<s;
        return false;
    }

    // 获取MIME类型和字符集
    QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
    QString charset = contentType.split("charset=").last();
    QString encoding = (charset.isEmpty()
                        || charset == "application/octet-stream")
            ? "UTF-8"
            : charset; // 默认使用UTF-8编码

//    qDebug()<<"busi code is : "<<busi_code;
//    qDebug()<<"contentType:"<<contentType;
//    qDebug()<<"charset:"<<charset;
//    qDebug()<<"encoding:"<<encoding;

    QByteArray bt = reply->readAll();

    if(!fileName.trimmed().isEmpty())
    {
        QString flnm = downloadPath + "/" + fileName.trimmed();

        QFile f(flnm);
        if(f.exists())
        {
            f.remove();
        }

        if(!f.open(QIODevice::WriteOnly)){
            QMessageBox::information(NULL, "注意", "建立下载文件失败！");
            qr.exec("update com_business set tmstmp = now(),infcode = -4, "
                    " v_out = '建立下载文件失败' where jyls = '" + currentMsgid + "'");
            return false;
        }

        f.write(bt);
        f.close();

        //文件下载，如体积小于1k，进行有效性验证

        if(bt.size() < 1024 )
        {
            QString t ;
            if(encoding == "UTF-8")
            {
                t = QString::fromUtf8(bt);
            }
            else
            {
                t = QString::fromLocal8Bit(bt);
            }
            //QString

            QJsonParseError json_error;
            QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
            if(json_error.error != 0 )
            {
                //json数据解析失败，数据内容应该是压缩包
                //不保存出参，只保存完成时间
                sq = "update com_business set tmstmp = now()  , infcode = "
                        + QString::number(jsonRet.value("code").toInt())
                         +  " where jyls = '" + currentMsgid + "'";
                if(!qr.exec(sq))
                {
                    qDebug()<<  busi_code + " 保存出参日志失败！";
                    qDebug()<<sq;
                }
                return true;
            }

            //解析json成功，一定是文件下载出错。
            jsonRet = jsdc.object();

            QString out_str = jsdc.toJson(QJsonDocument::Compact);
            out_str.replace("'","\\'");

            sq = "update com_business set tmstmp = now(),   v_out = '"
                    + out_str
                    + "' , infcode = "
                    + QString::number(jsonRet.value("code").toInt())
                    +  "  where jyls = '" + currentMsgid + "'";

            if(!qr.exec(sq))
            {
                qDebug()<<  busi_code + " 保存出参日志失败！";
                qDebug()<<sq;
            }

            info = busi_code + " 交易失败：" + jsonRet.value("err_msg").toString() ;
            return false ;

        }

        return true;
    }

    QString t ;
    if(encoding == "UTF-8")
    {
        t = QString::fromUtf8(bt);
    }
    else
    {
        t = QString::fromLocal8Bit(bt);
    }
    //QString

    QJsonParseError json_error;
    QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        info = "返回信息Json解析错误 " + json_error.errorString();
        qr.exec("update com_business set tmstmp = now(),infcode = -5, "
                "v_out = '" + info + "' where jyls = '" + currentMsgid + "'");
        return false;
    }
    //qDebug()<< " outDoc : "<<jsdc;

    jsonRet = jsdc.object();

    if(saveOut) //是否需要保存出参
    {
        QString out_str = jsdc.toJson(QJsonDocument::Compact);
        out_str.replace("'","\\'");

        sq = "update com_business set tmstmp = now(),   v_out = '"
                + out_str
                + "' , infcode = "
                + QString::number(jsonRet.value("code").toInt())
                 +  "  where jyls = '" + currentMsgid + "'";
    }
    else
    {
        //不保存出参，只保存完成时间
        sq = "update com_business set tmstmp = now()  , infcode = "
                + QString::number(jsonRet.value("code").toInt())
                 +  " where jyls = '" + currentMsgid + "'";
    }

    if(!qr.exec(sq))
    {
        qDebug()<<  busi_code + " 保存出参日志失败！";
        qDebug()<<sq;
    }

    if(jsonRet.value("code").toInt() != 0)
    {
        info = busi_code + " 交易失败：" + jsonRet.value("message").toString() ;
        return false ;
    }

    return true;
}

QString pub::gmssl_sm3(QString sour)
{

    //写入文件再读出，是为保证字符串格式。
    //Linux控制台传递参数字符集为 utf8， windows控制台为 GBK

    QTemporaryFile tmp_file;

    if (!tmp_file.open())
    {
        QMessageBox::information(NULL, "Note", "Temporary file open error.");
        return "";
    }

    tmp_file.write(sour.toLocal8Bit().data());

    tmp_file.close();

    QProcess process;

    process.start("gmssl sm3 -in " + tmp_file.fileName());

    if (!process.waitForStarted())
    {
        qDebug() << "gmssl 启动失败:" << process.errorString()<<"\n";
        return "";
    }

    if (!process.waitForFinished(5000))
    {
        qDebug() << "gmssl 执行超时\n";
        process.kill();
    }

    // 获取输出
    QByteArray output = process.readAllStandardOutput();
    QString result = QString::fromUtf8(output);
    qDebug() << "gmssl sm3 执行结果:" << result;

    return result;
}

QString pub::remove_trailing_zeros(const QString& number_str)
{
    // 使用正则表达式匹配数字格式（包括整数和小数）
    QRegularExpression regex("^(-?\\d+)\\.(\\d+)$");
    QRegularExpressionMatch match = regex.match(number_str);

    if (match.hasMatch()) {
        QString integerPart = match.captured(1);  // 整数部分
        QString decimalPart = match.captured(2);  // 小数部分

        // 移除小数部分尾部的 0
        int lastNonZero = -1;
        for (int i = decimalPart.length() - 1; i >= 0; --i) {
            if (decimalPart[i] != '0') {
                lastNonZero = i;
                break;
            }
        }

        if (lastNonZero >= 0) {
            // 还有有效的小数位
            decimalPart = decimalPart.left(lastNonZero + 1);
            return integerPart + "." + decimalPart;
        } else {
            // 所有小数位都是 0，直接返回整数部分
            return integerPart;
        }
    }

    // 如果不是小数格式，直接返回原字符串
    return number_str;
}
